【【spring源码】ApplicationListener事件监听底层原理
注:本文默认大家对spring IOC和AOP都比较熟,不会很赘述一些相关源码,如果有需要,可以参考:
- 【spring源码】spring容器IOC底层源码分析
- 【spring源码】AOP底层源码分析
- 【Spring源码】 后置处理器BeanPostProcessor底层原理分析
- 【spring源码】spring声明式事务底层源码分析
1.测试案例
- 手写一个事件监听类
/**
* 事件监听器
*
* @author wangjie
* @version V1.0
* @date 2020/1/9
*/
@Component
public class MyApplicationListener implements ApplicationListener<ApplicationEvent> {
//当容器中发布此事件以后,方法触发
@Override
public void onApplicationEvent(ApplicationEvent event) {
// TODO Auto-generated method stub
System.out.println("收到事件:"+event);
}
}
- 配置类
@ComponentScan(value = "com.code.ext")
@Configuration
public class ExtConfig {
@Bean
public User user(){
return new User("wangjie",18);
}
}
- 测试类:
public class IOCTest_EXT {
@Test
public void test01(){
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(ExtConfig.class);
applicationContext.publishEvent(new ApplicationEvent(new String("123")) {
@Override
public Object getSource() {
return super.getSource();
}
});
applicationContext.close();
}
}
- 运行结果:
收到事件:org.springframework.context.event.ContextRefreshedEvent[source=org.springframework.context.annotation.AnnotationConfigApplicationContext@47089e5f: startup date [Fri Jan 10 15:19:20 CST 2020]; root of context hierarchy]
一月 10, 2020 3:19:20 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext doClose
信息: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@47089e5f: startup date [Fri Jan 10 15:19:20 CST 2020]; root of context hierarchy
收到事件:com.code.test.IOCTest_EXT$1[source=123]
收到事件:org.springframework.context.event.ContextClosedEvent[source=org.springframework.context.annotation.AnnotationConfigApplicationContext@47089e5f: startup date [Fri Jan 10 15:19:20 CST 2020]; root of context hierarchy]
Process finished with exit code 0
2.源码分析
- 我们从测试用例进去
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(ExtConfig.class);
- 创建一个IOC容器,点进去:
public AnnotationConfigApplicationContext(Class... annotatedClasses) {
this();
//解析配置类,注册bean
this.register(annotatedClasses);
//spring的核心,在这个方法里,Spring完成了容器的初始化
this.refresh();
}
- 熟悉Spring源码的对refresh()这个方法应该不会陌生,spring的核心,我们点进去:
public void refresh() throws BeansException, IllegalStateException {
Object var1 = this.startupShutdownMonitor;
synchronized(this.startupShutdownMonitor) {
//容器刷新前的准备,设置上下文状态,获取属性,验证必要的属性等
this.prepareRefresh();
//获取新的beanFactory,销毁原有beanFactory、为每个bean生成BeanDefinition等
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
this.prepareBeanFactory(beanFactory);
try {
//配置标准的beanFactory,设置ClassLoader,设置SpEL表达式解析器,添加忽略注入的接口,添加bean,添加bean后置处理器等
this.postProcessBeanFactory(beanFactory);
//模板方法,此时,所有的beanDefinition已经加载,但是还没有实例化。
//允许在子类中对beanFactory进行扩展处理。比如添加ware相关接口自动装配设置,添加后置处理器等,是子类扩展
//pre