BeanPostProcessor: bean 後置處理器,bean 創建對象初始化前後進行攔截工作的
BeanFactoryPostProcessor: beanFactory 的後置處理器,在BeanFactory 標準初始化之後調用, 所有的 bean 定義 已經保存加載到 beanFactory 中, 但是 bean 的實例還沒有創建
BeanDefinitionRegistryPostProcessor:繼承於 BeanFactoryPostProcessor,postProcessBeanDefinitionRegistry()。在所有 bean 自定義信息將要被加載, bean 實例還未創建。 優先於 BeanFactoryPostProcessor 執行,利用 BeanDefinitionRegistryPostProcessor 給容器中添加一些組件
BeanPostProcessor.
BeanPostProcessor 中有兩個方法
public interface BeanPostProcessor {
Object postProcessBeforeInitialization(Object var1, String var2) throws BeansException;
Object postProcessAfterInitialization(Object var1, String var2) throws BeansException;
}
postProcessBeforeInitialization 方法在 bean對象的 init 方法之前執行。
postProcessAfterInitialization 方法在 bean 對象 init 方法之後執行
BeanPostProcessor
環境是 pom.xml中
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.12.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>4.3.12.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>4.3.12.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>RELEASE</version>
<scope>compile</scope>
</dependency>
創建一個 bean 對象
@Component
public class Car {
public Car(){
System.out.println("car constructor ");
}
public void init(){
System.out.println("car 。。。 init 。。。");
}
public void destory()
{
System.out.println("car .... destory");
}
}
創建一個類來實現 BeanPostProcessor
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("postProcessBeforeInitialization:" + beanName +" bean : " + bean);
return bean;
}
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("postProcessAfterInitialization:" + beanName +" bean : " + bean);
return bean;
}
}
配置類
@Configuration
@ComponentScan({"cn.fllday.beans"})
public class MainConfigOfLifeCycle {
@Bean(initMethod = "init",destroyMethod = "destory")
public Car car(){
return new Car();
}
}
測試類
public class IOCTest_LifeCycle {
@Test
public void test01(){
// 創建ioc容器
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfigOfLifeCycle.class);
System.out.println("容器創建完成");
context.close();
}
}
我們打斷點執行,查看執行語句
car constructor
postProcessBeforeInitialization:car bean : cn.fllday.beans.Car@258d79be
car 。。。 init 。。。
postProcessAfterInitialization:car bean : cn.fllday.beans.Car@258d79be
- 先執行 構造器,
- 然後執行postProcessBeforeInitialization
- 再次執行 init 方法,
- 在執行postProcessAfterInitialization 方法
- 每一個單例 bean 都會執行一遍
BeanDefinitionRegistryPostProcessor
- 在所有 bean 自定義信息將要被加載, bean 實例還未創建
- 優先於 BeanFactoryPostProcessor 執行,
- 利用 BeanDefinitionRegistryPostProcessor 給容器中添加一些組件
還是剛纔的例子 。 我們創建一個ExtBeanDefinitionRegistryPostProcessor.java
@Component
public class ExtBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
System.out.println("ExtBeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry。。。bean的數量: " + beanDefinitionRegistry.getBeanDefinitionCount());
RootBeanDefinition car = new RootBeanDefinition(Car.class);
beanDefinitionRegistry.registerBeanDefinition("person",car);
}
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
System.out.println("ExtBeanDefinitionRegistryPostProcessor.ExtBeanDefinitionRegistryPostProcessor 。。。 bean的數量:" + configurableListableBeanFactory.getBeanDefinitionCount());
}
}
beanDefinitionRegistry bean
定義信息的保存中心,以後 beanFactory 就是按照 BeanDefinitionRegistry 裏面保存的每一個bean 定義信息創建bean 實例
再次運行 剛剛的測試方法
ioc 容器開始初始化
3月 12, 2020 1:58:13 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@29f69090: startup date [Thu Mar 12 13:58:13 CST 2020]; root of context hierarchy
ExtBeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry。。。bean的數量: 9
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by org.springframework.cglib.core.ReflectUtils$1 (file:/C:/Users/gssznb/.m2/repository/org/springframework/spring-core/4.3.12.RELEASE/spring-core-4.3.12.RELEASE.jar) to method java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain)
WARNING: Please consider reporting this to the maintainers of org.springframework.cglib.core.ReflectUtils$1
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
ExtBeanDefinitionRegistryPostProcessor.ExtBeanDefinitionRegistryPostProcessor 。。。 bean的數量:10
postProcessBeforeInitialization:org.springframework.context.event.internalEventListenerProcessor bean : org.springframework.context.event.EventListenerMethodProcessor@275bf9b3
postProcessAfterInitialization:org.springframework.context.event.internalEventListenerProcessor bean : org.springframework.context.event.EventListenerMethodProcessor@275bf9b3
postProcessBeforeInitialization:org.springframework.context.event.internalEventListenerFactory bean : org.springframework.context.event.DefaultEventListenerFactory@12a94400
postProcessAfterInitialization:org.springframework.context.event.internalEventListenerFactory bean : org.springframework.context.event.DefaultEventListenerFactory@12a94400
postProcessBeforeInitialization:extConfig bean : cn.fllday.config.ExtConfig$$EnhancerBySpringCGLIB$$31ab2d3@5495333e
postProcessAfterInitialization:extConfig bean : cn.fllday.config.ExtConfig$$EnhancerBySpringCGLIB$$31ab2d3@5495333e
car constructor
postProcessBeforeInitialization:car bean : cn.fllday.beans.Car@b978d10
car 。。。 init 。。。
postProcessAfterInitialization:car bean : cn.fllday.beans.Car@b978d10
car constructor
postProcessBeforeInitialization:person bean : cn.fllday.beans.Car@5b7a8434
postProcessAfterInitialization:person bean : cn.fllday.beans.Car@5b7a8434
ioc 容器創建完成
3月 12, 2020 1:59:32 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext doClose
信息: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@29f69090: startup date [Thu Mar 12 13:58:13 CST 2020]; root of context hierarchy
car .... destory
**我們看到postProcessBeanDefinitionRegistry
先執行,然後通過該方法,定義了一個bean,未定義的時候, bean的數量爲9, 在使用postProcessBeanFactory
,發現bean 有 10 個。隨後在執行了。 構造方法,BeanPostProcessor類的 postProcessBeforeInitialization(),bean的init() 和 postProcessAfterInitialization() **
BeanFactoryPostProcessor
創建一個 BeanFactoryPostProcessor 類
ExtBeanFactoryPostProcessor.java
@Component
public class ExtBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("beanFacotry 執行");
int beanDefinitionCount = beanFactory.getBeanDefinitionCount();
System.out.println("查看當前容器中擁有 " + beanDefinitionCount + "個bean");
String[] beanDefinitionNames = beanFactory.getBeanDefinitionNames();
for (String name:beanDefinitionNames){
System.out.println("beanFactory 執行 ------------------------: " + name+", ");
}
System.out.println();
Car bean = (Car) beanFactory.getBean("car");
System.out.println(bean);
System.out.println("執行完成");
}
}
運行 剛纔的測試方法
打印結果
ioc 容器開始初始化
3月 12, 2020 11:52:06 上午 org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@573f2bb1: startup date [Thu Mar 12 11:52:06 CST 2020]; root of context hierarchy
ExtBeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry。。。bean的數量: 10
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by org.springframework.cglib.core.ReflectUtils$1 (file:/C:/Users/gssznb/.m2/repository/org/springframework/spring-core/4.3.12.RELEASE/spring-core-4.3.12.RELEASE.jar) to method java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain)
WARNING: Please consider reporting this to the maintainers of org.springframework.cglib.core.ReflectUtils$1
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
ExtBeanDefinitionRegistryPostProcessor.ExtBeanDefinitionRegistryPostProcessor 。。。 bean的數量:11
beanFacotry 執行
查看當前容器中擁有 11個bean
beanFactory 執行 ------------------------: org.springframework.context.annotation.internalConfigurationAnnotationProcessor,
beanFactory 執行 ------------------------: org.springframework.context.annotation.internalAutowiredAnnotationProcessor,
beanFactory 執行 ------------------------: org.springframework.context.annotation.internalRequiredAnnotationProcessor,
beanFactory 執行 ------------------------: org.springframework.context.event.internalEventListenerProcessor,
beanFactory 執行 ------------------------: org.springframework.context.event.internalEventListenerFactory,
beanFactory 執行 ------------------------: extConfig,
beanFactory 執行 ------------------------: extBeanDefinitionRegistryPostProcessor,
beanFactory 執行 ------------------------: extBeanFactoryPostProcessor,
beanFactory 執行 ------------------------: myBeanPostProcessor,
beanFactory 執行 ------------------------: car,
beanFactory 執行 ------------------------: person,
car constructor
cn.fllday.beans.Car@68267da0
執行完成
postProcessBeforeInitialization:org.springframework.context.event.internalEventListenerProcessor bean : org.springframework.context.event.EventListenerMethodProcessor@f381794
postProcessAfterInitialization:org.springframework.context.event.internalEventListenerProcessor bean : org.springframework.context.event.EventListenerMethodProcessor@f381794
postProcessBeforeInitialization:org.springframework.context.event.internalEventListenerFactory bean : org.springframework.context.event.DefaultEventListenerFactory@2e1d27ba
postProcessAfterInitialization:org.springframework.context.event.internalEventListenerFactory bean : org.springframework.context.event.DefaultEventListenerFactory@2e1d27ba
car constructor
postProcessBeforeInitialization:person bean : cn.fllday.beans.Car@61d6015a
postProcessAfterInitialization:person bean : cn.fllday.beans.Car@61d6015a
ioc 容器創建完成
可以看到最先執行的還是BeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry(),然後執行BeanDefinitionRegistryPostProcessor.ExtBeanDefinitionRegistryPostProcessor(),再然後BeanFactoryPostProcessor.postProcessBeanFactory(), 執行完之後,在開始創建bean 實例。 先執行 構造方法。然後BeanPostProcessor.postProcessBeforeInitialization()方法,再次執行 postProcessAfterInitialization()方法。在執行BeanFactoryProcessor的時候我們從 beanFactory中拿到了 car 實例。那麼 car 實例會被提前創建出來。執行 構造方法和 init 方法,但是並不會執行BeanPostProcessor中的postProcessBeforeInitialization方法和 postProcessAfterInitialization方法。當再次創建bean 實例的時候, 只會執行構造方法和 BeanPostProcessor中的postProcessBeforeInitialization方法和 postProcessAfterInitialization方法,init方法並不會執行