栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

BeanFactoryPostProcessor的调用时机

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

BeanFactoryPostProcessor的调用时机

BeanFactoryPostProcessor的调用时机

BeanFactoryPostProcessor其实就是BeanFactory(创建bean的工厂)的后置处理器。说起这个,你脑海中是不是泛起了回忆,是不是想起了有一个与BeanFactoryPostProcessor的名字极其相似的玩意,它就是BeanPostProcessor。那什么是BeanPostProcessor呢?我们之前早就说过了,它就是bean的后置处理器,并且是在bean创建对象初始化前后进行拦截工作的。

现在我们要讲解的是BeanFactoryPostProcessor,上面也说过了,它是BeanFactory(创建bean的工厂)的后置处理器。接下来,我们就要搞清楚它的内部原理了,想要搞清楚其内部原理,我们需要从它是什么时候工作这一点开始入手研究,也即搞清楚它的调用时机是什么。

我们点进去BeanFactoryPostProcessor的源码里面去看一看,发现它是一个接口,如下图所示。

仔细看一下其内部postProcessBeanFactory方法上的描述,这很重要,因为从这段描述中我们就可以知道BeanFactoryPostProcessor的调用时机。描述中说,我们可以在IOC容器里面的BeanFactory的标准初始化完成之后,修改IOC容器里面的这个BeanFactory。

也就是说,BeanFactoryPostProcessor的调用时机是在BeanFactory标准初始化之后,这样一来,我们就可以来定制和修改BeanFactory里面的一些内容了。那什么叫标准初始化呢?接着看描述,它说的是所有的bean定义已经被加载了,但是还没有bean被初始化。

说人话,就是BeanFactoryPostProcessor的调用时机是在BeanFactory标准初始化之后,这样一来,我们就可以来定制和修改BeanFactory里面的一些内容了,此时,所有的bean定义已经保存加载到BeanFactory中了,但是bean的实例还未创建。

案例实践

接下来,我们来编写一个案例来验证一下以上说的内容。

首先,我们来编写一个我们自己的BeanFactoryPostProcessor,例如MyBeanFactoryPostProcessor。要编写这样一个bean工厂的后置处理器,它得需要实现我们上面说的BeanFactoryPostProcessor接口,并且还得添加一个实现方法。由于BeanFactoryPostProcessor接口里面只声明了一个方法,即postProcessBeanFactory,所以咱们自己编写的MyBeanFactoryPostProcessor类中只需要实现其即可。

package com.baidu.bean;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Component;

import java.util.Arrays;

@Component
public class MainBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {

        System.out.println("MyBeanFactoryPostProcessor...postProcessBeanFactory..."); // 这个时候我们所有的bean还没被创建
        // 但是我们可以看一下通过Spring给我们传过来的这个beanFactory,我们能拿到什么

        int count = beanFactory.getBeanDefinitionCount(); // 我们能拿到有几个bean定义
        String[] names = beanFactory.getBeanDefinitionNames(); // 除此之外,我们还能拿到每一个bean定义的名字

        System.out.println("当前BeanFactory中有" + count + "个Bean");
        System.out.println(Arrays.asList(names));

    }

}

注意,我们自己编写的MyBeanFactoryPostProcessor类要想让Spring知道,并且还要能被使用起来,那么它一定就得被加在容器中,为此,我们可以在其上标注一个@Component注解。

然后,创建一个配置类,例如ExtConfig,记得还要在该配置类上使用@ComponentScan注解来配置包扫描哟!

当然了,我们也可以使用@Bean注解向容器中注入咱自己写的组件,例如,在这里,我们可以向容器中注入一个Blue组件。

package com.baidu.config;

import com.baidu.bean.Blue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;


@ComponentScan("com.baidu.bean")
@Configuration
public class ExtFactoryPostConfig {

   @Bean
   public Blue blue(){
       return new Blue();
   }

}

上面这个Blue组件其实就是一个非常普通的组件,代码如下所示:

package com.baidu.bean;

public class Blue {
    public Blue() {
        System.out.println("Blue-->无参的构造方法");
    }

    public void init(){
        System.out.println("Blue...init.....");
    }

    public void destory(){
        System.out.println("Blue...destory....");
    }
}

可以看到,在创建Blue对象的时候,无参构造器会有相应打印。

接着,编写一个单元测试类,例如IOCTest_Ext,来进行测试。

    @Test
    public void test01(){
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ExtFactoryPostConfig.class);

        //关闭容器
        context.close();

    }

测试啥呢?其实就是来验证一下BeanFactoryPostProcessor的调用时机。说得更具体一点就是,就是看一下咱们自己编写的BeanFactoryPostProcessor究竟是不是在所有的bean定义已经被加载,但是还未创建对象的时候工作?

那咱们接下来就来一探究竟。运行IOCTest_Ext类中的test01方法,可以看到Eclipse控制台打印出了如下内容。

哎呀!咱们自己编写的BeanFactoryPostProcessor在Blue类的无参构造器创建Blue对象之前就已经工作了。细心一点看的话,从bean的定义信息中还能看到Blue组件注册到容器中的名字,只是此刻还没创建对象,如下图所示。

说明BeanFactoryPostProcessor是在所有的bean定义信息都被加载之后才调用的。

https://liayun.blog.csdn.net/article/details/113103870

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/860269.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号