淺嘗Spring註解開發_簡單理解BeanFactoryPostProcessor、BeanDefinitionRegistryPostProcessor、ApplicationListener 淺嘗Spring註解開發,基於Spring 4.3.12 分析BeanFactoryPostProces ...
淺嘗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()
-