***的使用
- 定义事件
public class DemoEvent extends ApplicationEvent {
private String name;
public DemoEvent(Object source, String name) {
super(source);
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
- ***
- 方式一:接口实现***:
@Component
public class DemoListener implements ApplicationListener<DemoEvent> {
@Override
public void onApplicationEvent(DemoEvent event) {
System.out.println("事件"+event.getName()+"接口触发!");
}
}
- 方式二:注解***:
@Component
public class DemoAnnotationListener {
@EventListener
public void onEvent(DemoEvent event) {
System.out.println("事件"+event.getName()+"注解触发!");
}
}
- 发布事件
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
ConfigurableApplicationContext run = SpringApplication.run(DemoApplication.class, args);
run.publishEvent(new DemoEvent(run,"发布"));
}
}
***源码解析
***是观察者设计模式的实现。
在refresh()方发中调用了prepareRefresh()方法,预刷新上下文环境。
- 看下prepareRefresh()方法:
protected void prepareRefresh() {
/** * 创建一个早期事件***对象集合 */
if (this.earlyApplicationListeners == null) {
this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
}
else {
// Reset local application listeners to pre-refresh state.
this.applicationListeners.clear();
this.applicationListeners.addAll(this.earlyApplicationListeners);
}
/** * 创建一个容器用于保存早期待发布的事件集合 * 什么是早期事件? * 就是我们的事件***还没有注册到多播器上的时候都称为早期事件 * 早期事件不需要手动publishEvent发布, 在registerListeners中会自动发布, 发布完早期事件就不存在了。 */
this.earlyApplicationEvents = new LinkedHashSet<>();
}
- 创建事件多播器
initApplicationEventMulticaster()方法:
protected void initApplicationEventMulticaster() {
//获取我们的bean工厂对象
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
//判断容器中是没有有我们的applicationEventMulticaster 应用多播器组件
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
//直接显示的调用我们的getBean获取出来赋值给我们的applicationContext对象
this.applicationEventMulticaster =
beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
if (logger.isDebugEnabled()) {
logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
}
}
//容器中没有的话
else {
//spring ioc显示的new 一个SimpleApplicationEventMulticaster对象保存在applicatoinContext对象中
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
//并且注入到容器中
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
if (logger.isDebugEnabled()) {
logger.debug("Unable to locate ApplicationEventMulticaster with name '" +
APPLICATION_EVENT_MULTICASTER_BEAN_NAME +
"': using default [" + this.applicationEventMulticaster + "]");
}
}
}
AbstractApplicationEventMulticaster有属性ListenerRetriever,存储了所有的listener。
applicationListenerBeans只存储了***的名字,主要是为了捕获懒加载的***。
多播器负责存储***和后面广播事件。
- 注册*** registerListeners()
以上三步整个***就注册完成了。
看下发布事件的流程:
自定义多播器
自定义多播器可以选择监听事件是否异步执行。
@Configuration
@ComponentScan(basePackages = {
"com.tuling.event"})
@EnableAsync
public class MainConfig {
/* 往SimpleApplicationEventMulticaster设置taskExecutor则为异步事件 或者使用@Async */
@Bean(name = "applicationEventMulticaster")
public ApplicationEventMulticaster simpleApplicationEventMulticaster() {
SimpleApplicationEventMulticaster eventMulticaster
= new SimpleApplicationEventMulticaster();
eventMulticaster.setTaskExecutor(new SimpleAsyncTaskExecutor());
return eventMulticaster;
}
}