浅尝Spring注解开发_简单理解BeanFactoryPostProcessor、BeanDefinitionRegistryPostProcessor、ApplicationListener
浅尝Spring注解开发_简单理解BeanFactoryPostProcessor、BeanDefinitionRegistryPostProcessor、ApplicationListener
浅尝Spring注解开发,基于Spring 4.3.12
分析BeanFactoryPostProcessor、BeanDefinitionRegistryPostProcessor、ApplicationListener
浅尝Spring注解开发_自定义注册组件、属性赋值、自动装配
浅尝Spring注解开发_Bean生命周期及执行过程
浅尝Spring注解开发_AOP原理及完整过程分析(源码)
浅尝Spring注解开发_声明式事务及原理
浅尝Spring注解开发_简单理解BeanFactoryPostProcessor、BeanDefinitionRegistryPostProcessor、ApplicationListener
BeanFactoryPostProcessor
BeanPostProcessor
:bean后置处理器,bean创建对象初始化前后进行拦截工作的BeanFactoryPostProcessor
:beanFactory的后置处理器- 在
BeanFactory
标准初始化之后调用,来定制和修改BeanFactory
的内容 - 所有的bean定义已经保存加载到
beanFactory
,但是bean的实例还未创建
- 在
原理
- ioc容器创建对象
refresh()->invokeBeanFactoryPostProcessors(beanFactory)
- 如何找到所有的
BeanFactoryPostProcessor
并执行他们的方法?- 直接在
BeanFactory
中找到所有类型是BeanFactoryPostProcessor
的组件, - 按照
Ordered
接口排序 - 依次执行它们的方法。在初始化创建其他组件前面执行
- 直接在
- 如何找到所有的
@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("MyBeanFactoryPostProcessor...postProcessBeanFactory...");
int count = beanFactory.getBeanDefinitionCount();
String[] names = beanFactory.getBeanDefinitionNames();
System.out.println("当前BeanFactory中有"+count+" 个Bean");
System.out.println(Arrays.asList(names));
}
}
输出
MyBeanFactoryPostProcessor...postProcessBeanFactory...
当前BeanFactory中有9 个Bean
//[输出所有BeanDefinitionNames...]
//创建注入容器中的一个Bean
blue...constructor
BeanDefinitionRegistryPostProcessor
BeanDefinitionRegistryPostProcessor
- 继承自
BeanFactoryPostProcessor
:BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor
postProcessBeanDefinitionRegistry()
在所有bean定义信息将要被加载,bean实例还未创建
- 继承自
- 优先于
BeanFactoryPostProcessor
执行 - 利用
BeanDefinitionRegistryPostProcessor
给容器中再额外添加一些组件
原理
- ioc创建对象
refresh()->invokeBeanFactoryPostProcessors(beanFactory)
- 从容器中获取到所有的
BeanDefinitionRegistryPostProcessor
组件- 同样实现了
Ordered
接口排序,依次触发所有的postProcessBeanDefinitionRegistry()
方法 - 再来触发
BeanFactoryPostProcessor
方法postProcessBeanFactory()
- 同样实现了
@Component
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor{
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
// TODO Auto-generated method stub
System.out.println("MyBeanDefinitionRegistryPostProcessor...bean的数量:"+beanFactory.getBeanDefinitionCount());
}
//BeanDefinitionRegistry Bean定义信息的保存中心,以后BeanFactory就是按照BeanDefinitionRegistry里面保存的每一个bean定义信息创建bean实例;
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
// TODO Auto-generated method stub
System.out.println("postProcessBeanDefinitionRegistry...bean的数量:"+registry.getBeanDefinitionCount());
//再注册一个Bean,两种不同方法
//RootBeanDefinition beanDefinition = new RootBeanDefinition(Blue.class);
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(Blue.class).getBeanDefinition();
registry.registerBeanDefinition("hello", beanDefinition);
}
}
输出
//下面两个都是MyBeanDefinitionRegistryPostProcessor方法,由于在方法内又手动注册了一个,所以是11个
postProcessBeanDefinitionRegistry...bean的数量:10
MyBeanDefinitionRegistryPostProcessor...bean的数:11
//下面一个是BeanFactoryPostProcessor方法
MyBeanFactoryPostProcessor...postProcessBeanFactory...
当前BeanFactory中有11 个Bean
//输出所有BeanDefinitionNames...
[org.springframework...]
//两个Bean
blue...constructor
blue...constructor
ApplicationListener
-
ApplicationListener
:监听容器中发布的事件。事件驱动模型开发 -
public interface ApplicationListener<E extends ApplicationEvent>
:监听ApplicationEvent
及其下面的子事件
步骤
- 写一个监听器(
ApplicationListener
实现类)来监听某个事件(ApplicationEvent
及其子类),或者使用@EventListener
注解标注在监听方法上 - 把监听器加入到容器
- 只要容器中有相关事件的发布,我们就能监听到这个事件
ContextRefreshedEvent
:容器刷新完成(所有bean都完全创建)会发布这个事件ContextClosedEvent
:关闭容器会发布这个事件
- 发布一个事件
applicationContext.publishEvent()
自定义监听器
@Component
public class MyApplicationListener implements ApplicationListener<ApplicationEvent> {
//当容器中发布此事件以后,方法触发
@Override
public void onApplicationEvent(ApplicationEvent event) {
// TODO Auto-generated method stub
System.out.println("收到事件:"+event);
}
}
@Service
public class UserService {
@EventListener(classes={ApplicationEvent.class})
public void listen(ApplicationEvent event){
System.out.println("UserService..监听到的事件:"+event);
}
}
发布事件
public class IOCTest_Ext {
@Test
public void test01(){
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(ExtConfig.class);
//发布事件;
applicationContext.publishEvent(new ApplicationEvent(new String("我发布的事件")) {
});
applicationContext.close();
}
}
输出
//注入Bean
blue...constructor
//监听容器刷新事件
UserService..监听到的事件:org.springframework.context.event.ContextRefreshedEvent[]
收到事件:org.springframework.context.event.ContextRefreshedEvent[]
UserService..监听到的事件:com.atguigu.test.IOCTest_Ext$1[source=我发布的事件]
//监听自定义事件
UserService..监听到的事件:org.springframework.context.event.ContextClosedEvent[]
收到事件:com.atguigu.test.IOCTest_Ext$1[source=我发布的事件]
//监听容器关闭事件
UserService..监听到的事件:org.springframework.context.event.ContextClosedEvent
收到事件:org.springframework.context.event.ContextClosedEvent[]
原理
-
发布
ContextRefreshedEvent
事件为例:-
容器创建对象:
refresh()
-
finishRefresh()
,容器刷新完成事件发布流程:
-
获取事件的多播器(派发器):
getApplicationEventMulticaster()
-
multicastEvent
派发事件 -
获取到所有的
ApplicationListener
for (final ApplicationListener<?> listener : getApplicationListeners(event, type))
- 如果有
Executor
,可以支持使用Executor
进行异步派发:Executor executor = getTaskExecutor()
- 否则,同步的方式直接执行
listener
方法:invokeListener(listener, event)
- 拿到
listener
回调onApplicationEvent
方法
- 如果有
-
-
-
发布自定义事件
-
容器关闭发布
ContextClosedEvent
事件
事件多播器(派发器)
- 容器创建对象:
refresh()
initApplicationEventMulticaster()
:初始化ApplicationEventMulticaster
- 先去容器中找有没有
id="applicationEventMulticaster"
的组件 - 如果没有就创建一个:
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory)
,并且加入到容器中,我们就可以在其他组件要派发事件,自动注入这个applicationEventMulticaster
- 先去容器中找有没有
容器中有哪些监听器
- 容器创建对象:
refresh()
registerListeners()
- 从容器中拿到所有的监听器,把他们注册到
applicationEventMulticaster
中String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false)
- 将
listener
注册到ApplicationEventMulticaster
中getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName)
- 从容器中拿到所有的监听器,把他们注册到
SmartInitializingSingleton原理
@EventListener
使用EventListenerMethodProcessor
处理器来解析方法上的@EventListener
,EventListenerMethodProcessor
实现了SmartInitializingSingleton
-
ioc容器创建对象并
refresh()
-
finishBeanFactoryInitialization(beanFactory)
:初始化剩下的单实例bean-
先创建所有的单实例bean,
getBean()
-
获取所有创建好的单实例bean,判断是否是
SmartInitializingSingleton
类型的如果是就调用
afterSingletonsInstantiated()
-
自学咖网 » 浅尝Spring注解开发_简单理解BeanFactoryPostProcessor、BeanDefinitionRegistryPostProcessor、ApplicationListener