https://blog.csdn.net/weixin_42412601/article/details/104032552
BeanFactoryPostProcessor
的子接口,bean定义注册中心的后置处理器。
提供一个方法postProcessBeanDefinitionRegistry
,执行时机:在ioc容器初始化后,beanDefinition将要被加载,优先于BeanFactoryPostProcessor执行,注意:BeanFactoryPostProcessor
的postProcessBeanFactory
方法是在beanDefinition
加载完后,但是bean还没实例化之前执行。
自定义BeanDefinitionRegistryPostProcessor
:
@Component
public class MyBeanDefinitionRegisterPostProcessor implements BeanDefinitionRegistryPostProcessor {
//BeanDefinitionRegistry bean定义的保存中心
//以后BeanFactory就是按照BeanDefinitionRegistry里面保存的每一个bean定义信息创建bean实例
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
System.out.println("MyBeanDefinitionRegisterPostProcessor...postProcessBeanDefinitionRegistry");
System.out.println("bean定义数量:"+registry.getBeanDefinitionCount());
//手动注册一个Bean
// RootBeanDefinition rootBeanDefinition=new RootBeanDefinition(Car.class);
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(Car.class).getBeanDefinition();
registry.registerBeanDefinition("hello",beanDefinition);
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("MyBeanDefinitionRegisterPostProcessor...postProcessBeanFactory");
System.out.println("bean定义数量:"+beanFactory.getBeanDefinitionCount());
}
}
@Test
public void test(){
AnnotationConfigApplicationContext applicationContext=
new AnnotationConfigApplicationContext(ExtConfig.class);
applicationContext.close();
}
MyBeanDefinitionRegisterPostProcessor...postProcessBeanDefinitionRegistry
bean定义数量:9
MyBeanDefinitionRegisterPostProcessor...postProcessBeanFactory
bean定义数量:10
MyBeanFactoryPostProcessor...postProcessBeanFactory
当前BeanFactory中有BeanDefinition:10个
[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, myBeanDefinitionRegisterPostProcessor, myBeanFactoryPostProcessor, car, hello]
Car constructor....
Car constructor....
1、ioc创建对象;
2、refresh() -》invokeBeanFactoryPostProcessors(beanFactory);
3、从容器中获取到所有的BeanDefinitionRegistryPostProcessor组件。
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
(1)、按照优先级依次触发所有的postProcessBeanDefinitionRegistry()方法;
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
(2)、再来触发postProcessBeanFactory()方法BeanFactoryPostProcessor;
// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
4、再来从容器中找到BeanFactoryPostProcessor组件;然后依次触发postProcessBeanFactory()方法。
监听容器中发布的事件,事件驱动模型开发。public interface ApplicationListener
监听ApplicationEvent
及其下面的子事件
只要容器中有相应事件的发布,我们就能监听到这个事件;
ContextRefreshedEvent:容器刷新完成(所有bean都完全创建)会发布这个事件;
ContextClosedEvent:关闭容器会发布这个事件;
自定义监听器:通过实现ApplicationListener
接口来自定义监听器
@Component
public class MyApplicationListener implements ApplicationListener {
//当容器中发布此事件,方法触发
@Override
public void onApplicationEvent(ApplicationEvent event) {
System.out.println("收到事件:"+event);
}
}
自定义监听器方式二:注解的方式@EventListener
@Service
public class UserService {
//监听的事件类型
@EventListener(classes = {ApplicationEvent.class})
public void listen(ApplicationEvent applicationEvent){
//入参拿到的事件
System.out.println("UserService监听到的事件:"+applicationEvent);
}
}
测试:
@Test
public void test(){
AnnotationConfigApplicationContext applicationContext=
new AnnotationConfigApplicationContext(ExtConfig.class);
//自己发布事件
applicationContext.publishEvent(new ApplicationEvent(new String("我发布的事件")){});
applicationContext.close();
}
结果:这里监听到了三个事件,容器刷新完成事件,自己发布的事件,容器关闭事件
收到事件:org.springframework.context.event.ContextRefreshedEvent[source=org.springframework.context.annotation.AnnotationConfigApplicationContext@7907ec20, started on Sat Jan 18 22:01:55 CST 2020]
收到事件:spring.kz.kzTest$1[source=我发布的事件]
收到事件:org.springframework.context.event.ContextClosedEvent[source=org.springframework.context.annotation.AnnotationConfigApplicationContext@7907ec20, started on Sat Jan 18 22:01:55 CST 2020]
ContextRefreshedEvent,kzTest$1[source=我发布的事件],ContextClosedEvent
1.ContextRefreshedEvent事件
1.1容器创建对象:refresh();
1.2finishRefresh();容器刷新完成会发布ContextRefreshedEvent
事件
事件发布流程:
1.3publishEvent(new ContextRefreshedEvent(this));
发布容器刷新完成事件
1.3.1获取事件的多播器(派发器):getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
多播器就是把事件发给多个监听器
1.3.2multicastEvent(applicationEvent, eventType);
派发事件
1.3.3获取所有的getApplicationListeners
for (final ApplicationListener> listener : getApplicationListeners(event, type))
如果有Executor,可以支持使用Executor进行异步派发,Executor executor = getTaskExecutor();
否则使用同步的方式直接执行invokeListener(listener, event);
1.3.4执行Listener invokeListener(listener, event);
listener.onApplicationEvent(event);
拿到listener
回调onApplicationEvent
方法
2.自己发布的事件 事件发布流程同上
3.容器关闭发布ContextClosedEvent 事件发布流程同上
applicationContext.close()>doClose()->publishEvent(new ContextClosedEvent(this));
事件的多播器是怎么获取的呢?
1.容器创建对象:refresh()
2.initApplicationEventMulticaster();
初始化ApplicationEventMulticaster
2.1先去容器中找有没有自定义的id="applicationEventMulticaster"的组件
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
this.applicationEventMulticaster =
beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
有直接创建bean,赋值,初始化
2.2如果没有,自己手动创建并且加入到容器中,我们就可以在其他组件要派发事件,自动注入这个applicationEventMulticaster
组件
else {
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
容器中有哪些监听器
1.容器创建对象:refresh()
2.registerListeners(); 注册监听器
2.1从容器中获取所有的监听器定义,把它们注册到applicationEventMulticaster
多播器组件中
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
自定义多播器:
https://blog.csdn.net/pengweismile/article/details/92363266
使用EventListenerMethodProcessor
处理器来解析方法上的@EventListener
;该处理器实现了SmartInitializingSingleton
接口,该接口的afterSingletonsInstantiated
方法,执行时机为所有的单实例bean
创建完之后。
SmartInitializingSingleton
原理:
1.ioc容器创建并refresh()
2.finishBeanFactoryInitialization(beanFactory);
初始化剩下的单实例bean
-》preInstantiateSingletons()
2.1先创建所有的单实例bean
:遍历所有的beanDefinition
,然后getBean(beanName);
创建对象
2.2遍历创建好的所有的单实例bean
,判断是否实现了SmartInitializingSingleton
,如果是调用smartSingleton.afterSingletonsInstantiated();
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
}
}