spring注解-扩展原理

  AnnotationConfigApplicationContext(IOC容器)的有参构造方法中,在refresh()里对这些组件进行初始化

BeanPostProcessor

  bean后置处理器,bean创建对象初始化前后进行拦截工作的

BeanFactoryPostProcessor

  refresh()里的invokeBeanFactoryPostProcessors(beanFactory)来初始化BeanFactoryPostProcessor(beanFactory后置处理器,在所有的bean定义信息保存到beanFactory并进行标准初始化之后调用,来定制和修改BeanFactory的内容)

  • String[] postProcessorNames=beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false)
    • 从beanFactory中找到所有类型是BeanFactoryPostProcessor的组件,循环遍历postProcessorNames根据组件优先级加入到不同的集合里(实现了PriorityOrdered的直接在循环中就注册了beanFactoryPostProcessor,其余的之后再一次循环遍历进行注册)
    • 优先级高的集合先执行invokeBeanFactoryPostProcessors(postProcessors,beanFactory),该方法遍历调用postProcessors集合里的对象.postProcessBeanFactory(beanFactory)

BeanDefinitionRegistryPostProcessor

  继承BeanFactoryPostProcessor接口,在invokeBeanFactoryPostProcessors(beanFactory)中,在所有的bean定义信息将要被加载、BeanFactoryPostProcessor初始化之前进行工作

  • String[] postProcessorNames=beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
    • 从beanFactory中找到所有类型是BeanDefinitionRegistryPostProcessor的组件,也是根据优先级执行invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors,registry),之后依次触发所有的postProcessBeanDefinitionRegistry(registry)可以给容器中再额外添加一些组件

结论

  • invokeBeanFactoryPostProcessors()先从容器中获取到所有的BeanDefinitionRegistryPostProcessor组件(BeanDefinitionRegistryPostProcessor执行过的bean都会保存到一个集合里,执行到BeanFactoryPostProcessor的时候就会进行判断,如果存在说明已经执行过了)
  • 依次触发所有的postProcessBeanDefinitionRegistry()
  • 再来触发BeanFactoryPostProcessor.postProcessBeanFactory()
  • 最后再来从容器中找到BeanFactoryPostProcessor组件,然后依次触发postProcessBeanFactory()
@Component
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor{

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        // TODO Auto-generated method stub
        System.out.println("MyBeanDefinitionRegistryPostProcessor...bean的数量:"+beanFactory.getBeanDefinitionCount());
    }

    //BeanDefinitionRegistry Bean定义信息的保存中心,以后BeanFactory就是按照BeanDefinitionRegistry里面保存的每一个bean定义信息创建bean实例;
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        // TODO Auto-generated method stub
        System.out.println("postProcessBeanDefinitionRegistry...bean的数量:"+registry.getBeanDefinitionCount());
        //RootBeanDefinition beanDefinition = new RootBeanDefinition(Blue.class);
        AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(Blue.class).getBeanDefinition();
        registry.registerBeanDefinition("hello", beanDefinition);
    }

}

ApplicationListener

  监听容器中发布的事件;在refresh()里的registerListeners()里执行getBeanNamesForType(ApplicationListener.class, true, false)获取所有的监听事件,并将它们保存到ApplicationEventMulticaster的listener集合中

 public interface ApplicationListener<E extends ApplicationEvent>  //监听 ApplicationEvent 及其下面的子事件

步骤

  • 实现ApplicationListener接口来监听某个事件(ApplicationEvent及其子类)并加入到容器。只要容器中有相关事件的发布,我们就能监听到这个事件
    • ContextRefreshedEvent:容器刷新完成(所有bean都完全创建)会发布这个事件
    • ContextClosedEvent:关闭容器会发布这个事件
@Component
public class MyApplicationListener implements ApplicationListener<ApplicationEvent> {

    //当容器中发布此事件以后,方法触发
    @Override
    public void onApplicationEvent(ApplicationEvent event) {
        // TODO Auto-generated method stub
        System.out.println("收到事件:"+event);
    }

}
  • 发布事件
applicationContext.publishEvent(new ApplicationEvent(new String("我发布的时间")) {
        });

 原理

  • ContextRefreshedEvent
    • 在refresh()里的finishRefresh()中执行了publishEvent(new ContextRefreshedEvent(this));在容器刷新完成的最后一步方法里发布ContextRefreshedEvent事件
  • ContextClosedEvent
    • 执行applicationContext.close()关闭容器的doClose()中执行了publishEvent(new ContextClosedEvent(this))

  所有的事件发布都调用了publishEvent(),而在这方法里主要做了这几件事:

  • 获取事件的多播器(派发器):getApplicationEventMulticaster(),并通过multicastEvent()派发事件,在该方法中获取到所有的ApplicationListener进行遍历(如果有Executor,可以支持使用Executor进行异步派发;否则,同步的方式直接执行invokeListener(listener, event)),拿到listener回调onApplicationEvent()

 @EventListener

  使用EventListenerMethodProcessor处理器解析方法上的@EventListener,它实现SmartInitializingSingleton的afterSingletonsInstantiated();

  在refresh()里的finishBeanFactoryInitialization(beanFactory)里创建完所有单例bean后,会获取所有的bean判断是否是SmartInitializingSingleton类型的,如果是就调用afterSingletonsInstantiated()

@EventListener(classes={ApplicationEvent.class})
    public void listen(ApplicationEvent event){
        System.out.println("监听到的事件:"+event);
    }

事件的多播器

  在refresh()里的initApplicationEventMulticaster()中初始化ApplicationEventMulticaster,先去容器中找有没有id=“applicationEventMulticaster”的组件,如果没有this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);并通过beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster)注册到容器中去,在其他组件要派发事件就可以自动注入这个applicationEventMulticaster

原文地址:https://www.cnblogs.com/edda/p/13493780.html