Spring事件监听机制和状态机

Spring事件监听机制和Spring StateMachine都是基于观察者模式实现的,帮助业务代码进行解耦合。

Spring事件监听实现

Spring可以帮助开发者自己实现事件监听,开发者通过实现ApplicationListener(观察者Observer)接口定义一个监听器,同时通过实现ApplicationEvent(主题Subject)接口定义一个事件。实现ApplicationContextAware(发布器)通过发布器发布时间到ApplicationContext中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package com.souche.observer;
import org.springframework.context.ApplicationEvent;
/**
* 定义一个事件(主题 subject)
* define an event
*/
public class MyTestEvent extends ApplicationEvent {
public MyTestEvent(Object source) {
super(source);
}
@Override
public Object getSource() {
return super.getSource();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package com.souche.observer;

import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Service;

/**
* 创建另一个事件监听器
* 对于继承了 ApplicationEvent的事件所有入参对应的监听器都会监听到,执行onApplicationEvent方法
*/
@Service("myTestApplictionListener")
public class MyTestApplicationListener implements ApplicationListener<MyTestEvent> {

@Override
public void onApplicationEvent(MyTestEvent applicationEvent) {
System.out.println(applicationEvent.getClass());
if(applicationEvent instanceof MyTestEvent){
System.out.println("get to MyTestApplicationListener...");
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package com.souche.observer;

import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Service;

/**
* 创建一个事件监听器(观察者 observer)
* listener defination
*/
@Service("myApplicationListener")
public class MyApplicationListener implements ApplicationListener<MyTestEvent> {


@Override
public void onApplicationEvent(MyTestEvent applicationEvent) {
System.out.println(applicationEvent.getClass());
if(applicationEvent instanceof MyTestEvent){
System.out.println("get to MyApplicationListener");
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package com.souche.observer;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationEvent;
import org.springframework.stereotype.Service;
/**
* 创建一个事件发布器
*/
@Service("myPublisher")
public class MyPubisher implements ApplicationContextAware {

private ApplicationContext applicationContext;

public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext=applicationContext;
}
public void publishEvent(ApplicationEvent event){
System.out.println("into My Publisher's method to add event");
applicationContext.publishEvent(event);
}
}

启动一下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package com.souche.observer;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;

@SpringBootApplication
public class ObserverApplication {

public static void main(String[] args) {
ConfigurableApplicationContext configurableApplicationContext=SpringApplication.run(ObserverApplication.class, args);
MyPubisher myPubisher=(MyPubisher) configurableApplicationContext.getBean("myPublisher");
myPubisher.publishEvent(new MyTestEvent(1));
}
}

结果:

1
2
3
4
5
into My Publisher's method to add event
class com.souche.observer.MyTestEvent
get to MyApplicationListener
class com.souche.observer.MyTestEvent
get to MyTestApplicationListener...

可以通过@Order注解指定监听者的执行顺序。改善代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package com.souche.observer;

import org.springframework.context.ApplicationListener;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Service;

/**
* 创建另一个事件监听器
* 对于继承了 ApplicationEvent的事件所有入参对应的监听器都会监听到,执行onApplicationEvent方法
*/
@Order(1)
@Service("myTestApplictionListener")
public class MyTestApplicationListener implements ApplicationListener<MyTestEvent> {
@Override
public void onApplicationEvent(MyTestEvent applicationEvent) {
System.out.println(applicationEvent.getClass());
if(applicationEvent instanceof MyTestEvent){
System.out.println("get to MyTestApplicationListener...");
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package com.souche.observer;

import org.springframework.context.ApplicationListener;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Service;

/**
* 创建一个事件监听器(观察者 observer)
* listener defination
*/
@Order(2)
@Service("myApplicationListener")
public class MyApplicationListener implements ApplicationListener<MyTestEvent> {
@Override
public void onApplicationEvent(MyTestEvent applicationEvent) {
System.out.println(applicationEvent.getClass());
if(applicationEvent instanceof MyTestEvent){
System.out.println("get to MyApplicationListener");
}
}
}

结果:

1
2
3
4
5
into My Publisher's method to add event
class com.souche.observer.MyTestEvent
get to MyTestApplicationListener...
class com.souche.observer.MyTestEvent
get to MyApplicationListener