BeanFactoryPostProcessor是BeanFactory的后置处理器
在BeanFactory标准初始化之后调用,来定制和修改BeanFactory的内容
所有的Bean定义已经保存加载到BeanFactory,但是Bean的实例还未创建
//自定义实现BeanFactoryPostProcessor接口
@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("postProcessBeanFactory---bean size : " + beanFactory.getBeanDefinitionCount());
System.out.println("postProcessBeanFactory---bean is : " + Arrays.asList(beanFactory.getBeanDefinitionNames()));
}
}
//主配置类
@ComponentScan("com.learn.ext")
@Configuration
public class Extconfig {
@Bean
public HuaWei huaWei() {
return new HuaWei();
}
}
//Bean类
@Service
public class HuaWei {
public HuaWei() {
System.out.println("---HuaWei---Constructor---");
}
@PostConstruct
public void init() {
System.out.println("---HuaWei---init---");
}
@PreDestroy
public void destroy() {
System.out.println("---HuaWei---destroy---");
}
}
//容器初始化调用
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Extconfig.class);
applicationContext.close();
//输出结果
postProcessBeanFactory---bean size : 8
postProcessBeanFactory---bean is : [org.springframework.context.annotation.internalConfigurationAnnotationProcessor, org.springframework.context.annotation.internalAutowiredAnnotationProcessor, org.springframework.context.annotation.internalCommonAnnotationProcessor, org.springframework.context.event.internalEventListenerProcessor, org.springframework.context.event.internalEventListenerFactory, extconfig, myBeanFactoryPostProcessor, huaWei]
---HuaWei---Constructor---
---HuaWei---init---
----------------------------------------
---HuaWei---destroy---
//分析结果
在Bean实例化之前执行BeanFactoryPostProcessor
1.ioc容器的创建 refresh();
2.invokeBeanFactoryPostProcessors(beanFactory);
如何找到所有的BeanFactoryPostProcessor并执行他们的方法?
2.1 beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);直接在BeanFactory中找到所有类型是BeanFactoryPostProcessor的组件,
2.2 按照是否实现PriorityOrdered、或者Ordered、或者都未实现
2.3 分别依次执行postProcessor.postProcessBeanFactory(beanFactory);方法
3.在初始化创建其他组件前面执行
BeanDefinitionRegistryPostProcessor继承至BeanFactoryPostProcessor,自己定义了接口postProcessBeanDefinitionRegistry
在所有bean定义信息将要被加载,bean实例还未创建时,调用
优先于BeanFactoryPostProcessor执行,利用BeanDefinitionRegistryPostProcessor给容器额外添加一些组件。
//自定义BeanDefinitionRegistryPostProcessor实现BeanDefinitionRegistryPostProcessor接口
@Component
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
System.out.println("☆☆☆☆☆☆☆☆ postProcessBeanDefinitionRegistry bean count is " + registry.getBeanDefinitionCount());
RootBeanDefinition beanDefinition = new RootBeanDefinition(Blue.class);
registry.registerBeanDefinition("blue", beanDefinition);
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("☆☆☆☆☆☆☆☆ postProcessBeanFactory bean count is " + beanFactory.getBeanDefinitionCount());
System.out.println("☆☆☆☆☆☆☆☆ postProcessBeanFactory bean name is " + Arrays.asList(beanFactory.getBeanDefinitionNames()));
}
}
@Repository
public class Blue {
}
//输出结果
☆☆☆☆☆☆☆☆ postProcessBeanDefinitionRegistry bean count is 9
☆☆☆☆☆☆☆☆ postProcessBeanFactory bean count is 10
☆☆☆☆☆☆☆☆ postProcessBeanFactory bean name is [org.springframework.context.annotation.internalConfigurationAnnotationProcessor, org.springframework.context.annotation.internalAutowiredAnnotationProcessor, org.springframework.context.annotation.internalCommonAnnotationProcessor, org.springframework.context.event.internalEventListenerProcessor, org.springframework.context.event.internalEventListenerFactory, extconfig, myBeanDefinitionRegistryPostProcessor, myBeanFactoryPostProcessor, huaWei, blue]
postProcessBeanFactory---bean size : 10
postProcessBeanFactory---bean is : [org.springframework.context.annotation.internalConfigurationAnnotationProcessor, org.springframework.context.annotation.internalAutowiredAnnotationProcessor, org.springframework.context.annotation.internalCommonAnnotationProcessor, org.springframework.context.event.internalEventListenerProcessor, org.springframework.context.event.internalEventListenerFactory, extconfig, myBeanDefinitionRegistryPostProcessor, myBeanFactoryPostProcessor, huaWei, blue]
---HuaWei---Constructor---
---HuaWei---init---
----------------------------------------
---HuaWei---destroy---
//分析结果
优先于BeanFactoryPostProcessor执行,利用BeanDefinitionRegistryPostProcessor给容器额外添加一些组件,如Blue实例
1.容器对象的创建 refresh()方法执行
2.invokeBeanFactoryPostProcessors(beanFactory); 执行BeanFactory后置处理器
3.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
4.获取所有BeanDefinitionRegistryPostProcessor类型的后置处理器
4.1 First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
4.2 Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
4.3 Finally, 执行所以其他的BeanDefinitionRegistryPostProcessors
4.4 invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
依次执行postProcessor.postProcessBeanDefinitionRegistry(registry); //即自定义MyBeanDefinitionRegistryPostProcessor类中重载的postProcessBeanDefinitionRegistry方法
4.5 再从容器中找到BeanFactoryPostProcessor组件,然后依次触发postProcessProcessor() //即自定义类MyBeanDefinitionRegistryPostProcessor中重载的postProcessBeanFactory方法
AplicationListener:监听容器中发布的事件。事件驱动模型开发:
public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {
void onApplicationEvent(E event);
}
监听ApplicationEvent及其下面的子事件。
1.写一个监听器来监听某个程序(ApplicationEvent及其子类)
1.1 @EventListener(classes = {ApplicationEvent.class})
可以使用注解@EventListener实现监听的功能,
原理:使用EventListenerMethodProcessor处理器来解析方法上的@EventListener
EventListenerMethodProcessor实现了SmartInitializingSingleton接口,主要看看这个接口的源码,见下面源码分析
2.把监听器加入到Spring容器中
3.只要容器中有相关的事件的发布,我们就能监听到这个事件
ContextRefreshedEvent:容器刷新完成(所有bean都完成创建)会发布这个事件
ContextClosedEvent:关闭容器会发布这个事件
4.发布一个事件
//发布一个事件
applicationContext.publishEvent(new ApplicationEvent("custom_publish_event") {});
//自定义实现ApplicationListener接口,实现onApplicationEvent方法
@Component
public class MyApplicationListener implements ApplicationListener<ApplicationEvent> {
@Override
public void onApplicationEvent(ApplicationEvent event) {
System.out.println("收到事件..." + event);
}
}
public class AppTestExt {
@Test
public void shouldAnswerWithTrue() {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Extconfig.class);
//发布一个事件
applicationContext.publishEvent(new ApplicationEvent("custom_publish_event") {
});
System.out.println("----------------------------------------");
applicationContext.close();
}
}
//@EventListener注解使用
@Service
public class UserService {
@EventListener(classes = {ApplicationEvent.class})
public void listener(ApplicationEvent event) {
System.out.println("??????UserService.listener---" + event);
}
}
输出结果
☆☆☆☆☆☆☆☆ postProcessBeanDefinitionRegistry bean count is 11
☆☆☆☆☆☆☆☆ postProcessBeanFactory bean count is 12
☆☆☆☆☆☆☆☆ postProcessBeanFactory bean name is [org.springframework.context.annotation.internalConfigurationAnnotationProcessor, org.springframework.context.annotation.internalAutowiredAnnotationProcessor, org.springframework.context.annotation.internalCommonAnnotationProcessor, org.springframework.context.event.internalEventListenerProcessor, org.springframework.context.event.internalEventListenerFactory, extconfig, myApplicationListener, myBeanDefinitionRegistryPostProcessor, myBeanFactoryPostProcessor, userService, huaWei, blue]
postProcessBeanFactory---bean size : 12
postProcessBeanFactory---bean is : [org.springframework.context.annotation.internalConfigurationAnnotationProcessor, org.springframework.context.annotation.internalAutowiredAnnotationProcessor, org.springframework.context.annotation.internalCommonAnnotationProcessor, org.springframework.context.event.internalEventListenerProcessor, org.springframework.context.event.internalEventListenerFactory, extconfig, myApplicationListener, myBeanDefinitionRegistryPostProcessor, myBeanFactoryPostProcessor, userService, huaWei, blue]
---HuaWei---Constructor---
---HuaWei---init---
??????UserService.listener---org.springframework.context.event.ContextRefreshedEvent[source=org.springframework.context.annotation.AnnotationConfigApplicationContext@710726a3, started on Tue Jul 30 17:11:38 CST 2019]
收到事件...org.springframework.context.event.ContextRefreshedEvent[source=org.springframework.context.annotation.AnnotationConfigApplicationContext@710726a3, started on Tue Jul 30 17:11:38 CST 2019]
??????UserService.listener---com.learn.spring.AppTestExt$1[source=custom_publish_event]
收到事件...com.learn.spring.AppTestExt$1[source=custom_publish_event]
----------------------------------------
??????UserService.listener---org.springframework.context.event.ContextClosedEvent[source=org.springframework.context.annotation.AnnotationConfigApplicationContext@710726a3, started on Tue Jul 30 17:11:38 CST 2019]
收到事件...org.springframework.context.event.ContextClosedEvent[source=org.springframework.context.annotation.AnnotationConfigApplicationContext@710726a3, started on Tue Jul 30 17:11:38 CST 2019]
---HuaWei---destroy---
目前拦截到三个事件
ContextRefreshedEvent、AppTestExt$1[source=custom_event]、ContextClosedEvent
1.解析ContextRefreshedEvent事件
1.1 容器创建对象 调用refresh()方法
1.2 finishRefresh() 容器刷新完成
【事件发布流程】
1.3 publishEvent(new ContextRefreshedEvent(this));
1.3.1 首先获取事件的派发器(多播器)getApplicationEventMulticaster()
1.3.2 通过事件派发器对事件进行派发
getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
1.3.2.1 获取所有的ApplicationListener
for (ApplicationListener<?> listener : getApplicationListeners(event, type))
1)如果有Executor,可以支持使用Executor进行异步派发
2)否则,同步的方式直接执行Listener方法;invokeListener(listener, event));
拿到listener回调onApplicationEvent(event) 该方法即为自定义类MyApplicationListener实现的方法
【事件派发器(多播器)】
1.4 容器创建对象,refresh()
1.5 initApplicationEventMulticaster(); 初始化AplicationEventMulticaster
1.5.1 先在容器中找有没有applicationEventMulticaster的组件
1.5.2 如果没有就新建,this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);并加入到容器中。。我们可以在其他组件要派发事件时,自动注入这个applicationEventMulticaster
【容器中有哪些监听器】
1.6 容器创建对象,refresh()
1.7 registerListeners();
1.7.1 从容器中拿到所有的监听器,把它们注册到ApplicationEventMulticaster中
1.7.2 从容器中拿到实现了ApplicationListener接口的监听器,注册到ApplicationEventMulticaster
1.7.3 派发早期的事件getApplicationEventMulticaster().multicastEvent(earlyEvent);
2.注解@EventListener 的 SmartInitializingSingleton源码解析
2.1 ioc容器创建 refresh()
2.2 finishBeanFactoryInitialization()初始化剩下的danshiliBean
2.3 beanFactory.preInstantiateSingletons();
2.3.1 先创建所有的单实例bean getBean();
2.3.2 获取所有创建好的单实例bean 判断是否为SmartInitializingSingleton类型
如果是就调用smartSingleton.afterSingletonsInstantiated();