Spring的BeanFactoryPostProcessor和BeanPostProcessor

PostProcessor:后处理器; 
BeanPostProcessor:Bean的后置处理器(处理的对象是Bean); 
BeanFactoryPostProcessor:BeanFactory的后置处理器(处理的对象是BeanFactory)

(1)看一下BeanFactoryPostProcessor接口的源码:

@FunctionalInterface
public interface BeanFactoryPostProcessor {

    /**
     * Modify the application context‘s internal bean factory after its standard
     * initialization. All bean definitions will have been loaded, but no beans
     * will have been instantiated yet. This allows for overriding or adding
     * properties even to eager-initializing beans.
     * @param beanFactory the bean factory used by the application context
     * @throws org.springframework.beans.BeansException in case of errors
     */
    void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}

①方法postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)的作用是什么? 
源码中是这样说明的:

//Modify the application context‘s internal bean factory after its standard initialization.

bean factory已经经历了standard initialization; 
方法的入参ConfigurableListableBeanFactory beanFactory即是standard initialization后的bean factory; 
把standard initialization后的bean factory交给我们处理,我们可以对其进行修改。 
②什么时候调用postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)? 
源码中是这样说明的:

// All bean definitions will have been loaded, but no beans will have been instantiated yet.

bean factory已经经历了standard initialization,所有的bean definitions也已经被加载到bean factory之中,但是还没有创建(实例化)任何的Bean。 
③方法的入参beanFactory 
方法的入参ConfigurableListableBeanFactory beanFactory即是我们需要处理的对象;beanFactory已经经历了standard initialization,所有的bean definitions也已经被加载到beanFactory之中。 
④如何操作(处理)beanFactory呢? 
操作beanFactory的常见方式: 
对加载到beanFactory中的bean definitions进行修改。

通过参数beanFactory,可以获取相关Bean的bean definition,并修改bean definition。

(2)代码示例: 
User类:

public class User {
    private String username;
    private int age;

    public void setUsername(String username) {
        System.out.println("setUsername()");
        this.username = username;
    }

    public void setAge(int age) {
        System.out.println("setAge()");
        this.age = age;
    }

    public User(){
        System.out.println("Constructor()");
    }

    @Override
    public String toString() {
        return "User [username=" + username + ", age=" + age + "]";
    }

}

BeanFactoryPostProcessor处理器:

public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    public MyBeanFactoryPostProcessor(){
        System.out.println("BeanFactoryPostProcessor实现类的构造器");
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        System.out.println("BeanFactoryPostProcessor.postProcessBeanFactory()");

        //获取指定的BeanDefinition
        BeanDefinition bd = beanFactory.getBeanDefinition("user1");
        //根据BeanDefinition获取MutablePropertyValues
        MutablePropertyValues pvs = bd.getPropertyValues();

        //增加
        pvs.add("age", 20);
        //覆盖
        pvs.add("username", "Richard");
    }
}

Bean配置文件:

    <bean id="user1" class="com.User">
        <!-- 这里只为属性username赋值,属性age没有赋值 -->
        <property name="username" value="Jack"></property>
    </bean>

    <bean class="com.MyBeanFactoryPostProcessor"></bean>

测试类:

    public static void main(String[] args) {
        ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");

        User user1=(User)context.getBean("user1");
        System.out.println(user1);
    }

运行结果:

BeanFactoryPostProcessor实现类的构造器 
BeanFactoryPostProcessor.postProcessBeanFactory() 
Constructor() 
setUsername() 
setAge() 
User [username=Richard, age=20]

(3)注意点: 
BeanFactoryPostProcessor接口和BeanPostProcessor接口非常相似,都是spring初始化bean时对外暴露的扩展点。

①BeanFactory的后置处理器:Spring提供的一种特殊的Bean 
②BeanFactory的后置处理器,需要实现BeanFactoryPostProcessor接口 
③需要在Bean的配置文件中,注册BeanFactory的后置处理器,但不需要设置id属性。IOC容器会自动识别这是个BeanFactory的后置处理器,自动的使用它。

<bean class="com.MyBeanFactoryPostProcessor"></bean>

④实例化BeanFactoryPostProcessor实现类,并调用BeanFactoryPostProcessor的postProcessBeanFactory()方法; 
这2步会很早进行,在Bean实例被创建之前进行。 
⑤Bean的后置处理器,操作的对象是Bean,会对容器中的所有Bean进行处理,每个Bean都要经过2个处理方法postProcessBeforeInitialization()和postProcessAfterInitialization(); 
BeanFactory的后置处理器,操作的对象是BeanFactory,因此只会有一次处理过程(很早进行,在Bean实例被创建之前进行),即只调用处理方法postProcessBeanFactory()一次。

时间: 2024-10-09 13:07:44

Spring的BeanFactoryPostProcessor和BeanPostProcessor的相关文章

Spring中BeanFactoryPostProcessor的详解

Spring中BeanFactoryPostProcessor和BeanPostProcessor都是Spring初始化bean时对外暴露的扩展点.两个接口从名字看起来很相似,但是作用及使用场景却不同. Spring IoC容器允许BeanFactoryPostProcessor在容器实例化任何bean之前读取bean的定义(配置元数据),并可以修改它.同时可以定义多个BeanFactoryPostProcessor,通过设置'order'属性来确定各个BeanFactoryPostProces

spring 后置处理器BeanFactoryPostProcessor和BeanPostProcessor的用法和区别

主要区别就是: BeanFactoryPostProcessor可以修改BEAN的配置信息而BeanPostProcessor不能,下面举个例子说明 BEAN类: [java] view plaincopy package com.springdemo.postProcessor; public class PostProcessorBean { private String username; private String password; public String getPassword

《玩转Spring》第二章 BeanPostProcessor扩展

上一章,介绍了如何扩展spring类实现自动读取配置文件. 这一章,我们介绍如何通过实现BeanPostProcessor接口,对容器中的Bean做一层代理,来满足我们的个性化需求. 一.基本原理 我很不想贴代码,显得太没水平.有时候自己的语言又很空洞,不得不贴代码,感觉用代码来说明一件事反而更容易些. import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.

BeanFactoryPostProcessor和BeanPostProcessor的区别

题意: 给你ABCD四个集合,集合中数的个数都为N(N<=4000),如果分别在ABCD四个集合中取一个数,a b c d ,求有多少种可能使得a+b+c+d=0. 当然你可以尝试枚举所有的组合,绝对可以计算出结果,大概有N^4种吧,如果你有足够的时间还是可以算出来的,哈哈. 当然我不是用上面一种方法计算的,那样算肯定超时. 我的做法是求出所有a+b 到ab数组中, 和所有 c+d到cd数组中,然后排序,枚举每个ab,用二分在cd中查找有没有可能组成0.  有个问题就是二分只能返回一个结果,所以

转-Spring bean处理-InitializingBean&amp;BeanPostProcessor&amp;BeanFactoryPostProcessor

转自  http://elim.iteye.com/blog/2017466 执行顺序: BeanFactoryPostProcessor.postProcessBeanFactoryUserBean's constructorUserBean 's username property setBeanPostProcessor.postProcessBeforeInitializationInitializingBean.afterPropertiesSetBeanPostProcessor.p

Spring Custom Bean with BeanPostProcessor

Spring Custom Bean 1.BeanPostProcessors 这个接口是在spring容器初始化完bean之后 才会被调用,这个接口针对是一个容器,不能夸容器操作的,这个只能在初始化bean之后再改变一些自己的内容,如果想改变bean的结构,需要另外的一个接口:BeanFactoryPostProcessor

[spring源码学习]-BeanPostProcessor的使用

一.接口描述 spring提供了一个接口类-BeanPostProcessor,我们叫他:bean的加工器,应该是在bean的实例化过程中对bean做一些包装处理,里边提供两个方法 public interface BeanPostProcessor { public abstract Object postProcessBeforeInitialization(Object obj, String s) throws BeansException; public abstract Object

spring源码之BeanPostProcessor

前言 spring的强大点之一,在于它给我们提供了许多的扩展点,其中非常重要的一个接口就是BeanPostProcessor. 概述 我们可以IOC的依赖注入阶段分为三个阶段,即实例化,属性注入.初始化.在分析之前,先来熟悉下几个接口BeanPostProcessor.InstantiationAwareBeanPostProcessor.SmartInstantiationAwareBeanPostProcess.MergedBeanDefinitionPostProcessor接口.这几个接

八、spring生命之器之BeanPostProcessor

BeanPostProcessor我们一般称为Bean的后置处理器,它与我们前面介绍的InitialingBean.init-method等一样,都是在bean的初始化时被调用,具体的用法我们在举例中进行学习. 要使用BeanPostProcessor非常简单,只要实现这个接口即可. 在此之前,我们来先看下我们的Cat类,我们的目的是将这个Cat注册进spring的ioc容器中,并让这个BeanPostProcessor起到作用. public class Cat implements Init