扩展

BeanFactoryPostProcessor

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

BeanFactoryPostProcessor: beanFactory的后置处理器,在Beanfactory标准初始化之后调用;所有的Bean定义已经保存加载到beanFactory/.但是Ban实例还未创建

实现接口的Bean:

@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        System.out.println("postProcessBeanFactory");
        int count = beanFactory.getBeanDefinitionCount();
        String[] names = beanFactory.getBeanDefinitionNames();
        System.out.println("当前BeanFactory中有"+count+"个Bean");
        System.out.println(Arrays.asList(names));
        
    }

}

 config:

@Configuration
@ComponentScan("com.toov5.ExtBean")
public class ExtConfig {
    @Bean
    public Boss boss() {
        return new Boss();
    }
}

Test:

public class test {
    @Test 
    public void test01(){    
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(ExtConfig.class);
        applicationContext.close();
      }  
} 

结果: 看到执行过程如下

步骤:

   1  ioc容器创建对象

   2 invokeBeanFactoryPostProcessors(beanFactory) ; 执行BeanfactoryPostProcessor; 如何找到所有的BeanFactoryPostProcessor并执行他们的方法

        a,直接在BeanFactory中找到所有类型是BeanfactoryPostProcessor的组件,并执行他们的方法。

        b,在初始化创建其他组件前面执行  

MyBeanDefinitionRegistryPostProcessor :
@Component
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {

    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        System.out.println("BeanDefinitionRegistryPostProcessor..bean的数量"+beanFactory.getBeanDefinitionCount());
        
    }
   //BeanDefinitionRegistry  Bean定义信息的保存中心  以后BeanFactory就是按照BeanDefinitionRegistry里面保存的每一个Bean定义信息创建bean实例
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        System.out.println("BeanDefinitionRegistryPostProcessor..Bean的数量"+registry.getBeanDefinitionCount());
        //可以自己注册Bean
        //    RootBeanDefinition beanDefinition = new RootBeanDefinition(Car.class);
       //或者这样,与上面效果是一样的
        AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(Car.class).getBeanDefinition();
        registry.registerBeanDefinition("helloBeanName", beanDefinition);
    }

}

 执行test方法后:

  

 可以看出 优先于 

BeanFactoryPostProcessor  执行

利用 

BeanDefinitionRegistryPostProcessor  给容器中再额外添加一些组件

原理: 

    1 ioc创建对象

    2 refresh() ---> invokeBeanFactoryPostProcessors(beanFactory)

   3 从容器中获取到所有的BeanDefinitionRegistryPostProcessor组件

     1 一次触发所有的postProcessBeanDefinitionRegistry() 方法

     2 再来触发postProcessBeanFactory() 方法 

ApplicationListener: 监听容器中发布的时间。时间 驱动模型开发

    public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {

      监听ApplicationEvent 及其下面的子事件

容器刷新事件 容器关闭事件

 步骤:

   1 写一个监听器来监听某个事件(ApplicationEvent及其子类)

   2 把监听器注册到容器中

   3 只要容器中有相关事件的发布,就能监听到这个事件

     ContextRefreshedEvent: 容器刷新完成(所有bean都完全创建) 会发布事件

     ContextClosedEvent: 关闭容器会发布这个事件

 4 发布一个事件

    

监听:

@Component 
public class MyApplicationListener implements ApplicationListener<ApplicationEvent>{
   //当容器中 发布此事件以后 方法触发
    public void onApplicationEvent(ApplicationEvent event) {
         
        System.out.println("收到事件"+event);
    }

}

test:  发布了一个事件

public class test {
    @Test 
    public void test01(){    
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(ExtConfig.class);
        //发布事件
        applicationContext.publishEvent(new ApplicationEvent(new String("我发布的时间")) {
        });
        applicationContext.close();
      }  
} 

结果:

原理:

  ContextRefreshedEvent事件

       1、容器创建对象 refresh()  

       2、 finishRefresh() 容器刷新完成,容器刷新完成会发布ContextRefreshedEvent事件。我们也可以自己发布事件,容器关闭会发布事件

       3、publishEvent(new ContextRefreshedEvent(this) )

            事件发布流程:

                     获取事件的多播器(派发器): getApplicationEventMulticaster()

                     multicastEvent派发事件

                     获取到所有的ApplicationListener: 如果有Executor 可以支持使用Executor进行异步派发,否则,同步的方法直接知心Listener方法 invokeListener(listener, event)

                     拿到listener回调onApplicationEvent方法

                            

@EventListener   跟实现Listener接口实现的效果是一样的

   service

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

 config

  

@Configuration
@ComponentScan("com.toov5.service")
public class ExtConfig {
    @Bean
    public Boss boss() {
        return new Boss();
    }
}

test:

public class test {
    @Test 
    public void test01(){    
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(ExtConfig.class);
        //发布事件
        applicationContext.publishEvent(new ApplicationEvent(new String("我发布的时间")) {
        });
        applicationContext.close();
      }  
} 

结果:

 监听器的实现ApplicationListener监听某个事件, ApplicationEvent及其子类

 @EventListener

原理: 使用EventListenerMethodProcessor处理器来解析方法上的@EcentListener

SmatInitializationSingleton原理 

   ioc容器创建对象并refresh()

   finishBeanFactoryInitialization(beanFactory) 初始化剩下的单实例bean

           先创建所有的单实例bean getBean()

          获取所有创建好的单实例bean,判断是否是SmartInitatializingSingleton类型的。是就调用afterSingletonInstantiated() 

原文地址:https://www.cnblogs.com/toov5/p/10687177.html