一、Spring Event-Driven architure
Spring 事件机制 是观察者模式的一种实现(这里需要一个观察者模式文章链接跳转)。Spring 事件在中间加了 一个 EventMultiCaster 作为中间者,用来管理,事件的接收和传递。
spring 实现事件监听自定义:需要继承 ApplicationEvent 和 实现 ApplicationListener 其本质,也是 EventObject 和 EventListener
二、模拟Spring 事件监听
定义一个任务事件和一个任务事件监听器
任务事件 TaskEvent.java
/**
* <p>任务事件</p>
*/
public class TaskEvent extends ApplicationEvent {
public TaskEvent(Object source) {
super(source);
}
}
事件监听 TaskListener.java
/**
* <p>任务事件监听器</p>
*/
public class TaskListener implements ApplicationListener<TaskEvent> {
@Override
public void onApplicationEvent(TaskEvent taskEvent) {
System.out.println(" 获取到数据源:" + taskEvent.getSource());
}
}
测试 Event.java
public class EventTest {
public static void main(String[] args) throws Exception{
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
// 事件监听
context.addApplicationListener(new TaskListener());
// 启动 IOC容器
context.refresh();
context.publishEvent(new TaskEvent("任务事件"));
System.in.read();
}
}
测试结果
获取到数据源:任务事件
三、Web开发模拟事件监听机制
准备环境
和上面 的 事件 TaskEvent.java 和 事件监听 TaskListener.java 一致
方式一
启动类注册 任务监听事件
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication springApplication = new SpringApplication();
ConfigurableApplicationContext run = springApplication.run(Application.class, args);
run.addApplicationListener(new TaskListener());
}
}
方式二
在配置文件(application.properties)中添加
context.listener.classes=com.qguofeng.webdemo.TaskListener
方式三
直接在 Listener 头上加 @Component
/**
* <p>任务事件监听器</p>
*/
@Component
public class TaskListener implements ApplicationListener<TaskEvent> {
@Override
public void onApplicationEvent(TaskEvent taskEvent) {
System.out.println(" 获取到数据源:" + taskEvent.getSource());
}
}
测试控制器
@RestController
public class TaskController {
@RequestMapping("/event/demo")
public String eventWebDemo(){
ListenerPush_1.push(new TaskEvent("任务事件发送"));
return "发送成功";
}
@RequestMapping("/event/demo2")
public String eventWebDemo2(){
ListenerPush_2.push(new TaskEvent("任务事件发送"));
return "发送成功";
}
}
两种消息发送
方式一:ListenerPush_1
/**
* 事件发送工具 1
*/
@Component
public class ListenerPush_1 implements ApplicationContextAware {
private static ApplicationContext context;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
ListenerPush_1.context = applicationContext;
}
public static void push(ApplicationEvent event) {
context.publishEvent(event);
}
}
方式二:ListenerPush_2
@Component
public class ListenerPush_2 implements ApplicationEventPublisherAware {
private static ApplicationEventPublisher applicationEventPublisher;
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
this.applicationEventPublisher = applicationEventPublisher;
}
public static void push(ApplicationEvent event){
applicationEventPublisher.publishEvent(event);
}
}
其本质时一样的,都是通过 ApplicationEventPublisher 来进行事件发送
四、总结
使用 方式三在生产环境中,因为 @Component 的使用,也方便 @Autowired 进行 注入,实现复杂功能更方便