【spring源码】ApplicationListener事件监听底层原理

本文深入探讨了Spring框架中事件监听的实现机制,包括ApplicationListener接口的使用和@EventListener注解的底层源码分析。通过一个测试案例,逐步解析了事件从触发到派发的过程,涉及容器刷新、事件多播器的初始化和监听器的注册。最后,文章还介绍了在所有单例预实例化阶段,如何通过EventListenerMethodProcessor处理器处理@EventListener注解的方法,完成事件监听的注册。
摘要由CSDN通过智能技术生成

【【spring源码】ApplicationListener事件监听底层原理

注:本文默认大家对spring IOC和AOP都比较熟,不会很赘述一些相关源码,如果有需要,可以参考:

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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值