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()