在spring启动刷新的时候,会有一个准备工作也就是prepareBeanFactory方法,里面会添加BeanPostProcessor,也就是本文要说的ApplicationListenerDetector
prepareBeanFactory(beanFactory);
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
....
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
....
}
ApplicationListenerDetector属于BeanPostProcessor类型,所以任何bean的实例化,包括spring自带的bean,只要调用doGetBean创建bean实例化,就会走到BeanPostProcessor的回调方法中,只不过此时BeanPostProcessor的数量,比较少,还没把用户自定义的BeanPostProcessor添加进来。
ApplicationListenerDetector:主要作用:
在任何Bean初始化完成之后:如果Bean是单例的则并且bean是ApplicationListener类型,则加入到this.applicationListeners中,applicationListeners会在广播通知的时候,会遍历监听者发送通知在任何Bean销毁之前: 如果Bean是ApplicationListener类型,则会从ApplicationEventMulticaster(事件广播器)中删除。
比如我们平时用到的spring事件功能:ApplicationEvent+ApplicationListener
下面是部分源码:
class ApplicationListenerDetector implements DestructionAwareBeanPostProcessor, MergedBeanDefinitionPostProcessor {
//初始化之前
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
if (bean instanceof ApplicationListener) {//判断bean是否ApplicationListener类型
Boolean flag = this.singletonNames.get(beanName);//判断是否是单利
if (Boolean.TRUE.equals(flag)) {
this.applicationContext.addApplicationListener((ApplicationListener>) bean);
}
else if (Boolean.FALSE.equals(flag)) {
if (logger.isWarnEnabled() && !this.applicationContext.containsBean(beanName)) {
.....
}
this.singletonNames.remove(beanName);
}
}
return bean;
}
//销毁之前
@Override
public void postProcessBeforeDestruction(Object bean, String beanName) {
if (bean instanceof ApplicationListener) {
try {
ApplicationEventMulticaster multicaster = this.applicationContext.getApplicationEventMulticaster();
multicaster.removeApplicationListener((ApplicationListener>) bean);
multicaster.removeApplicationListenerBean(beanName);
}
catch (IllegalStateException ex) {
}
}
}
}
为什么要加下面2个判断
if (bean instanceof ApplicationListener)//判断bean是否ApplicationListener类型 Boolean flag = this.singletonNames.get(beanName);//判断是否是单利 if (Boolean.TRUE.equals(flag))
因为任何一个bean实例化,都会处理走所有的BeanPostProcessor处理器,所以要判断是否是需要处理的那种类型bean,将非相关的bean排除掉



