前言
上一篇介绍了国际化的应用以及初始化音讯源的源码,接下来接着往下浏览,将进入 initApplicationEventMulticaster、onRefresh 和 registerListeners 的相干操作逻辑。
这一部分次要是初始化事件播送器以及注册监听器。而 onRefresh 局部则须要子类去实现。所以本文次要介绍以下几个局部:
- 什么是 Spring 事件?
- 监听器是如何应用的?
什么是 Spring 事件?
这块的介绍在官网 1.15.2. Standard and Custom Events 局部有介绍。
Spring 通过 ApplicationEvent 类和 ApplicationListener 接口提供 ApplicationContext 中的事件处理。如果将实现 ApplicationListener 接口的 bean 部署到上下文中,则每次将 ApplicationEvent 公布到 ApplicationContext 时,都会告诉该 bean。实质上,这是规范的观察者设计模式。
演绎下来次要就是三个局部: 事件、事件发布者、事件监听器。
- 事件:ApplicationEvent,要自定义事件,则须要创立一个类继承 ApplicationEvent。
- 事件发布者:ApplicationEventPublisher 和 ApplicationEventMulticaster,因为 ApplicationContext 实现了 ApplicationEventPublisher,所以事件公布能够间接应用 ApplicationContext。
- 事件监听器:ApplicationListener,通过创立一个实现了 ApplicationListener 并注册为 Spring bean 的类来接管音讯。
Spring 也提供了也有一些内置的监听器,能够在官网查看,这里就不做介绍了。
应用监听器
简略来说次要分为以下几个局部:
- 注册事件
- 注册监听器
- 公布事件
在接口调用公布事件时,监听器就会做出相应的操作。
1. 注册事件
创立 MyApplicationEvent
类并继承 ApplicationEvent
public class MyApplicationEvent extends ApplicationEvent {
private static final long serialVersionUID = 5366526231219883438L;
private String message;
/**
* Create a new {@code ApplicationEvent}.
*
* @param source the object on which the event initially occurred or with
* which the event is associated (never {@code null})
*/
public MyApplicationEvent(Object source, String message) {super(source);
this.message = message;
}
public String getMessage() {return message;}
}
2. 注册监听器
@Component
public class MyApplicationListener implements ApplicationListener<MyApplicationEvent> {
@Override
public void onApplicationEvent(MyApplicationEvent event) {System.out.println("MyApplicationListener 收到音讯:" + event.getMessage());
}
}
当然这里也能够应用注解 @EventListener
的形式来应用。
@Component
public class MyAnnotationApplicationListener {@EventListener(classes = MyApplicationEvent.class)
public void myApplicationEventListener(MyApplicationEvent event) {System.out.println("应用注解的形式, 收到事件:" + event.getMessage());
}
}
3. 应用
因为 AnnotationConfigApplicationContext 实现了 ApplicationContext,而 ApplicationContext 实现了 ApplicationEventPublisher,所以这块传入以后 context 是没有问题的。
public class AnnotationConfigApplicationTest {public static void main(String[] args) {AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.register(JavaConfig.class);
context.refresh();
MyApplicationEvent myApplicationEvent = new MyApplicationEvent(context, "呼叫土豆, 呼叫土豆!");
context.publishEvent(myApplicationEvent);
}
}
日志输入:
源码局部
initApplicationEventMulticaster
这块和下面初始化音讯源相似,都是查找指定名称的 Bean,如果找不到,则本人应用默认的。
protected void initApplicationEventMulticaster() {ConfigurableListableBeanFactory beanFactory = getBeanFactory();
// 是否蕴含 applicationEventMulticaster Bean
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
this.applicationEventMulticaster =
beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
if (logger.isTraceEnabled()) {logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
}
}
else {
// 应用 SimpleApplicationEventMulticaster 创立一个 事件公布器
SimpleApplicationEventMulticaster simpleApplicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
simpleApplicationEventMulticaster.setApplicationStartup(getApplicationStartup());
this.applicationEventMulticaster = simpleApplicationEventMulticaster;
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
if (logger.isTraceEnabled()) {
logger.trace("No'" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "'bean, using" +
"[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
}
}
}
onRefresh
这块须要子类去实现,我这里通过断电,临时没有进去。所以就不介绍了。
registerListeners
protected void registerListeners() {
// 增加实现 ApplicationListener 作为侦听器的 bean。// 不会影响其余侦听器,能够将它们增加为非 bean。// Register statically specified listeners first.
// 先注册动态指定的监听器
for (ApplicationListener<?> listener : getApplicationListeners()) {getApplicationEventMulticaster().addApplicationListener(listener);
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let post-processors apply to them!
// 只是增加 并没有执行
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
// Publish early application events now that we finally have a multicaster...
// 公布晚期的工夫, 并且将 earlyApplicationEvents 设置为空
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {for (ApplicationEvent earlyEvent : earlyEventsToProcess) {getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
总结
这篇文章次要内容是介绍 Spring 事件的应用,同时简略介绍了 initApplicationEventMulticaster、onRefresh 和 registerListeners 局部的源码。
相干举荐
- Spring 源码学习 13:initMessageSource
- Spring 源码学习 12:registerBeanPostProcessors
- Spring 源码学习 11:invokeBeanFactoryPostProcessors