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方法并不会执行