spring扩展原理

Posted programmlover

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring扩展原理相关的知识,希望对你有一定的参考价值。

一  BeanFactoryPostProcessor的作用及原理:

1、BeanFactoryPostProcessor的作用:在BeanFactory标准初始化之后调用,所有的bean已保存加载到beanFactory,但是bean的实例还未创建

2、示例:

@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor{

    //这个方法会在bean实例创建之前调用
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        System.out.println("postProcessBeanFactory...");
        String[] beanDefinitionNames = beanFactory.getBeanDefinitionNames();
        int beanDefinitionCount = beanFactory.getBeanDefinitionCount();
        System.out.println("当前beanFactory中有"+ beanDefinitionCount +"个bean,这些bean的名字是"+Arrays.toString(beanDefinitionNames));
        
    }

}

3、原理:查看构造器 public AnnotationConfigApplicationContext(Class<?>... annotatedClasses),

public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
        this();
        register(annotatedClasses);
        refresh();
    }

    我们会发现构造器调用了refresh()方法,进入refresh()方法

public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            // Prepare this context for refreshing.
            prepareRefresh();

            // Tell the subclass to refresh the internal bean factory.
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
            //第一步,预创建bean对象
            // Prepare the bean factory for use in this context.
            prepareBeanFactory(beanFactory);

            try {
                
                //第二步,调用invokeBeanFactoryPostProcessors(beanFactory)方法
                // Invoke factory processors registered as beans in the context.
                invokeBeanFactoryPostProcessors(beanFactory);
                ...;
                //初始化bean对象实例
                // Instantiate all remaining (non-lazy-init) singletons.
                finishBeanFactoryInitialization(beanFactory);
                ...;
    }

    我们会发现 invokeBeanFactoryPostProcessors 在创建bean对象之后且在初始化bean实例之前调用,这就是他的原理

    进入invokeBeanFactoryPostProcessors ,再进入 PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

    这个方法会直接在BeanFactory中找到所有类型为BeanFactoryPostProcessor的方法并且执行他们。

 

二  BeanFactoryPostProcessor 子接口 BeanDefinitionRegistryPostProcessor接口的作用:

1、BeanDefinitionRegistryPostProcessor 新增了一个方法: void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;

  这个方法的作用:  在所有bean信息将要被加载,bean实例还未创建时调用,所以 postProcessBeanDefinitionRegistry方法将会优先于 postProcessBeanFactory方法被调用

2、示例:

@Component
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor{

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        int beanDefinitionCount = beanFactory.getBeanDefinitionCount();
        System.out.println("当前beanFactory中有"+ beanDefinitionCount +"个bean");
        
    }

    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        System.out.println("当前beanFactory中有"+ registry.getBeanDefinitionCount() +"个bean");
        AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(Dog.class).getBeanDefinition();
        registry.registerBeanDefinition("newAddBean", beanDefinition);
        
    }

}

 

三  ApplicationListener 的用法:

1、  ApplicationListener 作用:监听容器中发布的事件。事件驱动模型开发。

     ApplicationListener 接口定义:public interface ApplicationListener<E extends ApplicationEvent> extends EventListener

    1) 监听范围:监听 ApplicationEvent 及其下面的子类

      ContextClosedEvent  //Context关闭事件

      ContextRefreshedEvent  //Context刷新事件

      ContextStartedEvent  //Context开始事件

      ContextStoppedEvent  //Context停止事件

2、基于事件驱动模型开发步骤:

  1) 写一个监听器来监听某个事件,这个事件必须是 ApplicationEvent 及其下面的子类

  2) 把监听器加入容器中

  3)只要容器中有相关类型事件发布,我们就能监听到这个事件

3、示例

@Component
public class MyApplicationListener implements ApplicationListener<ApplicationEvent>{

    //当容器中发布此事件,方法会得到触发
    @Override
    public void onApplicationEvent(ApplicationEvent event) {
        System.out.println("收到事件:"+event);
        
    }

}

 

四 ApplicationListener 原理

1、ContextRefreshedEvent事件:
   1)、容器创建对象:refresh();
   2)、refresh() 调用 finishRefresh();容器刷新完成会发布ContextRefreshedEvent事件

   3)、finishRefresh() 调用 publishEvent(new ContextRefreshedEvent(this));

【事件发布流程】: publishEvent(new ContextRefreshedEvent(this));
   1)、publishEvent 方法获取事件的多播器(派发器):getApplicationEventMulticaster()
   2)、multicastEvent派发事件:
   3)、multicastEvent方法获取到所有的ApplicationListener;
     for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {
       1)、if (有Executor) {

          可以支持使用Executor进行异步派发;
           Executor executor = getTaskExecutor();

         } else {

          同步的方式直接执行listener方法;invokeListener(listener, event);

           拿到listener回调onApplicationEvent方法;

         }
 【事件多播器(派发器)】
   1)、容器创建对象:refresh();
   2)、refresh() 方法调用 initApplicationEventMulticaster();初始化ApplicationEventMulticaster;
   1)、先去容器中找有没有id=“applicationEventMulticaster”的组件;
   2)、如果没有this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
       并且加入到容器中,我们就可以在其他组件要派发事件,自动注入这个applicationEventMulticaster

【容器中有哪些监听器】
   1)、容器创建对象:refresh();
   2)、refresh() 调用 registerListeners() :从容器中拿到所有的监听器,把他们注册到applicationEventMulticaster中;
                     String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
   3)、 //将listener注册到ApplicationEventMulticaster中: getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName)

 

五  @Listener注解的应用:

1、@Listener用法:@EventListener(classes= { ${class event ApplicationEvent} ,...}) ,将这个注解标在方法上spring在启动的时候就会将这个方法创建成一个监听器,

  注意:方法中必须要有一个ApplicationEvent及其子类的参数来接收事件

2、示例:

@Service
public class ListenerService {

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

 

六  @Listener的原理:

1、@Listener 使用 EventListenerMethodProcessor来处理

2、EventListenerMethodProcessor 实现了 SmartInitializingSingleton 接口,主要就是这个接口在起作用

3、SmartInitializingSingleton 原理:afterSingletonsInstantiated() 方法

   1)、ioc容器创建对象并refresh();
   2)、finishBeanFactoryInitialization(beanFactory);初始化剩下的单实例bean;
     1)、先创建所有的单实例bean;getBean();
     2)、获取所有创建好的单实例bean,判断是否是SmartInitializingSingleton类型的;
       如果是就调用afterSingletonsInstantiated();























以上是关于spring扩展原理的主要内容,如果未能解决你的问题,请参考以下文章

Spring全注解开发--扩展原理

spring扩展原理

Spring注解驱动开发-----扩展原理

spring注解开发-扩展原理(源码)

spring-AOP原理

spring中依赖注入的原理