理解Spring中的BeanPostProcessor、BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor

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
  1. 先执行 构造器,
  2. 然后执行postProcessBeforeInitialization
  3. 再次执行 init 方法,
  4. 在执行postProcessAfterInitialization 方法
  5. 每一个单例 bean 都会执行一遍

BeanDefinitionRegistryPostProcessor

  1. 在所有 bean 自定义信息将要被加载, bean 实例还未创建
  2. 优先于 BeanFactoryPostProcessor 执行,
  3. 利用 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 容器开始初始化
312, 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 容器创建完成
312, 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 容器开始初始化
312, 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方法并不会执行

结束: 看到的小伙伴发现有问题 ,希望指正

发布了167 篇原创文章 · 获赞 28 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/qq_40990836/article/details/104779495