自定义一个实现ApplicationListener接口的类:
@Component
public class MyApplicationListener implements ApplicationListener<MyApplicationEvent> {
@Override
public void onApplicationEvent(MyApplicationEvent event) {
System.out.println("我是测试监听器的类方法:"+event.getSource());
}
}
这里使用了@Component注解,此注解下节分析;
然后再自定义一个触发事件:
public class MyApplicationEvent extends ApplicationEvent {
public MyApplicationEvent(Object source) {
super(source);
}
}
要达到的效果就是,当请求发布的事件是MyApplicationEvent事件的时候,就需要调用自定义的监听器;
执行结果:
可以看到执行的结果就是想要的结果。那么代码是如何实现这一点的呢?
这里只看关键代码,首先要找到AbstractApplicationContext#refresh的方法,其中最后第二步实例化方法是finishBeanFactoryInitialization(beanFactory)方法,它是通过getBean(beanName)来实例化剩余的单利的;
在此过程中,会调用如下方法:
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
看方法名称可知,其实初始化后应用bean的后置处理器的方法;
即调用了ApplicationListenerDetector的BeanPostProcessor的后置处理器,它实现了MergedBeanDefinitionPostProcessor接口,
注(在此之前已经执行):
所以在这之前,它会在doCreateBean的实例化之后调用其后置处理器的postProcessMergedBeanDefinition()方法,此处是将自定义的监听器添加到singletonNames中。
然后接着上面继续,它后置方法postProcessAfterInitialization():
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
if (bean instanceof ApplicationListener) {
// potentially not detected as a listener by getBeanNamesForType retrieval
Boolean flag = this.singletonNames.get(beanName);
if (Boolean.TRUE.equals(flag)) {
// singleton bean (top-level or inner): register on the fly
this.applicationContext.addApplicationListener((ApplicationListener<?>) bean);
}
else if (Boolean.FALSE.equals(flag)) {
if (logger.isWarnEnabled() && !this.applicationContext.containsBean(beanName)) {
// inner bean with other scope - can't reliably process events
logger.warn("Inner bean '" + beanName + "' implements ApplicationListener interface " +
"but is not reachable for event multicasting by its containing ApplicationContext " +
"because it does not have singleton scope. Only top-level listener beans are allowed " +
"to be of non-singleton scope.");
}
this.singletonNames.remove(beanName);
}
}
return bean;
}
此时,先判断了一下对象是否是ApplicationListener类型,如果是,则添加到this.defaultRetriever.applicationListeners变量中,取值的时候,则会根据具体的类型进行判断
for (ApplicationListener<?> listener : listeners) {
if (supportsEvent(listener, eventType, sourceType)) {
if (retriever != null) {
filteredListeners.add(listener);
}
allListeners.add(listener);
}
}
此时,就会将根据事件类型,添加相应的监听器,然后调用对应的onApplicationEvent方法。
当然,此处也可以使用spi的形式注入或者@Bean的形式都可以;
监听器可以实现线程上下文的的热更新等功能。