Spring之Beanpostprocessor and Beanfactorypostprocessor使用

BeanFactoryPostProcessor

官方类的注释

**
 * Factory hook that allows for custom modification of an application context's
 * bean definitions, adapting the bean property values of the context's underlying
 * bean factory.
 *
 * <p>Useful for custom config files targeted at system administrators that
 * override bean properties configured in the application context. See
 * {@link PropertyResourceConfigurer} and its concrete implementations for
 * out-of-the-box solutions that address such configuration needs.
 *
 * <p>A {@code BeanFactoryPostProcessor} may interact with and modify bean
 * definitions, but never bean instances. Doing so may cause premature bean
 * instantiation, violating the container and causing unintended side-effects.
 * If bean instance interaction is required, consider implementing
 * {@link BeanPostProcessor} instead.
 *
 * <h3>Registration</h3>
 * <p>An {@code ApplicationContext} auto-detects {@code BeanFactoryPostProcessor}
 * beans in its bean definitions and applies them before any other beans get created.
 * A {@code BeanFactoryPostProcessor} may also be registered programmatically
 * with a {@code ConfigurableApplicationContext}.
 *
 * <h3>Ordering</h3>
 * <p>{@code BeanFactoryPostProcessor} beans that are autodetected in an
 * {@code ApplicationContext} will be ordered according to
 * {@link org.springframework.core.PriorityOrdered} and
 * {@link org.springframework.core.Ordered} semantics. In contrast,
 * {@code BeanFactoryPostProcessor} beans that are registered programmatically
 * with a {@code ConfigurableApplicationContext} will be applied in the order of
 * registration; any ordering semantics expressed through implementing the
 * {@code PriorityOrdered} or {@code Ordered} interface will be ignored for
 * programmatically registered post-processors. Furthermore, the
 * {@link org.springframework.core.annotation.Order @Order} annotation is not
 * taken into account for {@code BeanFactoryPostProcessor} beans.
 *

1.允许自定义修改应用程序上下文的bean定义,调整上下文底层的bean属性值。
2.对于针对系统管理员的自定义配置文件非常有用,重写在应用程序上下文中配置的bean属性。查看{@link PropertyResourceConfigurer}及其具体实现,解决此类配置需求的现成解决方案。
3.一个可以与bean交互并修改bean定义,但从来没有bean实例。如果bean过早的实例化,违反容器并导致意外的副作用。*如果需要bean实例交互,请考虑实现*改为{@link beanoptprocessor}。
4.注册{@code ApplicationContext}自动检测{@code BeanFactoryPostProcessor}并在创建任何其他bean之前应用它们。*{@code BeanFactoryPostProcessor}也可以通过编程方式注册*使用{@code ConfigurableApplicationContext}。
5.订购{@code BeanFactoryPostProcessor}在*{@code ApplicationContext}将根据*{@链接org.springframework.core.PriorityOrdered}和*{@链接org.springframework.core.Ordered}语义自动检测;。相反,*{@code BeanFactoryPostProcessor}以编程方式注册的bean使用{@code ConfigurableApplicationContext}将按以下顺序应用注册;通过实现的{@code PriorityOrdered}或{@code Ordered}接口将被忽略以编程方式注册的后处理器。此外{@链接org.springframework.core.注释.顺序@Order}注释不是考虑{@codebeanfactorypostprocessor}bean。
 

方法:postProcessBeanFactory的注释

/**
	 * 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;

.根据应用程序上下文的标准修改应用程序上下文的内部bean工厂初始化。所有bean定义都将被加载,但没有bean将被实例化。这允许重写或添加属性,甚至急于初始化bean。

                                                                                                                                            --------------以上译文源于百度翻译

简而言之就是spring启动过程中,bean工厂创建完成以后,并把所有加载的bean定义写入bean工厂,此时bean工厂中只有bean的定义信息,没有实例化;可以通过实现BeanFactoryPostProcessor接口,来修改bean信息,也可以提前实例化bean修改属性;但是官方不建议这么做,如果bean过早的实例化,违反容器并导致意外的副作用。*如果需要bean实例交互,请考虑实现*改为{@link beanoptprocessor}。

下面只是一个demo,暂不考虑副作用等;

Demo:

自定义的MyBeanFactoryPostProcessor类实现BeanFactoryPostProcessor接口,并重写postProcessBeanFactory方法
package com.ppc.spring;

import com.ppc.spring.controller.UserController;
import com.ppc.spring.service.UserService;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;

public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
        System.out.println("*****获取UserController对象*****");
        UserController userController = (UserController) configurableListableBeanFactory.getBean("userController");
        System.out.println("*****创建UserService对象*****");
        UserService userService = new UserService(); //这里只为演示,创建一个UserService对象
        System.out.println("*****给userController设置userService属性*****");
        userController.setUserService(userService);//给userController赋值,等spring启动完成查看userController是否有userService对象

    }
}
UserController类
package com.ppc.spring.controller;

import com.ppc.spring.service.UserService;

public class UserController {

    private UserService userService;


    public UserService getUserService() {
        return userService;
    }

    public void setUserService(UserService userService) {
        this.userService = userService;
    }


    public UserController() {
        System.out.println(" UserController 构造函数");
    }


    public void execute(){

    }

    @Override
    public String toString() {
        return "UserController{" +
                "userService=" + userService +
                '}';
    }
}

UserService类

package com.ppc.spring.service;

public class UserService {

    public UserService() {
        System.out.println("UserService 构造函数");

    }

    @Override
    public String toString() {
        return "UserService{}";
    }
}

配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

	<bean id="userController" class="com.ppc.spring.controller.UserController"></bean>

	<bean id="myFactoryBeanProcessor" class="com.ppc.spring.MyBeanFactoryPostProcessor"></bean>

</beans>

测试类:

package com.ppc.spring;


import com.ppc.spring.controller.UserController;
import org.junit.jupiter.api.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpringTest {

    @Test
    public void test(){
        ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("springmvc.xml");
        UserController userController = classPathXmlApplicationContext.getBean("userController", UserController.class);
        System.out.println(userController);
    }

}

测试结果:

G:\software\jdk\bin\java.exe -ea -Didea.test.cyclic.buffer.size=1048576 "-javaagent:G:\soft_install\ideaIU\IntelliJ IDEA 2019.1.1\lib\idea_rt.jar=3575:G:\soft_install\ideaIU\IntelliJ IDEA 2019.1.1\bin" -Dfile.encoding=UTF-8 -classpath "G:\soft_install\ideaIU\IntelliJ IDEA 2019.1.1\lib\idea_rt.jar;G:\soft_install\ideaIU\IntelliJ IDEA 2019.1.1\plugins\junit\lib\junit-rt.jar;G:\soft_install\ideaIU\IntelliJ IDEA 2019.1.1\plugins\junit\lib\junit5-rt.jar;C:\Users\ppc\.m2\repository\org\junit\platform\junit-platform-launcher\1.6.2\junit-platform-launcher-1.6.2.jar;C:\Users\ppc\.m2\repository\org\apiguardian\apiguardian-api\1.1.0\apiguardian-api-1.1.0.jar;C:\Users\ppc\.m2\repository\org\junit\platform\junit-platform-engine\1.6.2\junit-platform-engine-1.6.2.jar;C:\Users\ppc\.m2\repository\org\opentest4j\opentest4j\1.2.0\opentest4j-1.2.0.jar;C:\Users\ppc\.m2\repository\org\junit\platform\junit-platform-commons\1.6.2\junit-platform-commons-1.6.2.jar;G:\software\jdk\jre\lib\charsets.jar;G:\software\jdk\jre\lib\deploy.jar;G:\software\jdk\jre\lib\ext\access-bridge-64.jar;G:\software\jdk\jre\lib\ext\cldrdata.jar;G:\software\jdk\jre\lib\ext\dnsns.jar;G:\software\jdk\jre\lib\ext\jaccess.jar;G:\software\jdk\jre\lib\ext\jfxrt.jar;G:\software\jdk\jre\lib\ext\localedata.jar;G:\software\jdk\jre\lib\ext\nashorn.jar;G:\software\jdk\jre\lib\ext\sunec.jar;G:\software\jdk\jre\lib\ext\sunjce_provider.jar;G:\software\jdk\jre\lib\ext\sunmscapi.jar;G:\software\jdk\jre\lib\ext\sunpkcs11.jar;G:\software\jdk\jre\lib\ext\zipfs.jar;G:\software\jdk\jre\lib\javaws.jar;G:\software\jdk\jre\lib\jce.jar;G:\software\jdk\jre\lib\jfr.jar;G:\software\jdk\jre\lib\jfxswt.jar;G:\software\jdk\jre\lib\jsse.jar;G:\software\jdk\jre\lib\management-agent.jar;G:\software\jdk\jre\lib\plugin.jar;G:\software\jdk\jre\lib\resources.jar;G:\software\jdk\jre\lib\rt.jar;D:\CODE\MAYUN\spring-source-analysis\target\test-classes;D:\CODE\MAYUN\spring-source-analysis\target\classes;C:\Users\ppc\.m2\repository\org\springframework\boot\spring-boot-starter-web\2.3.0.RELEASE\spring-boot-starter-web-2.3.0.RELEASE.jar;C:\Users\ppc\.m2\repository\org\springframework\boot\spring-boot-starter\2.3.0.RELEASE\spring-boot-starter-2.3.0.RELEASE.jar;C:\Users\ppc\.m2\repository\org\springframework\boot\spring-boot\2.3.0.RELEASE\spring-boot-2.3.0.RELEASE.jar;C:\Users\ppc\.m2\repository\org\springframework\boot\spring-boot-autoconfigure\2.3.0.RELEASE\spring-boot-autoconfigure-2.3.0.RELEASE.jar;C:\Users\ppc\.m2\repository\org\springframework\boot\spring-boot-starter-logging\2.3.0.RELEASE\spring-boot-starter-logging-2.3.0.RELEASE.jar;C:\Users\ppc\.m2\repository\ch\qos\logback\logback-classic\1.2.3\logback-classic-1.2.3.jar;C:\Users\ppc\.m2\repository\ch\qos\logback\logback-core\1.2.3\logback-core-1.2.3.jar;C:\Users\ppc\.m2\repository\org\apache\logging\log4j\log4j-to-slf4j\2.13.2\log4j-to-slf4j-2.13.2.jar;C:\Users\ppc\.m2\repository\org\apache\logging\log4j\log4j-api\2.13.2\log4j-api-2.13.2.jar;C:\Users\ppc\.m2\repository\org\slf4j\jul-to-slf4j\1.7.30\jul-to-slf4j-1.7.30.jar;C:\Users\ppc\.m2\repository\jakarta\annotation\jakarta.annotation-api\1.3.5\jakarta.annotation-api-1.3.5.jar;C:\Users\ppc\.m2\repository\org\yaml\snakeyaml\1.26\snakeyaml-1.26.jar;C:\Users\ppc\.m2\repository\org\springframework\boot\spring-boot-starter-json\2.3.0.RELEASE\spring-boot-starter-json-2.3.0.RELEASE.jar;C:\Users\ppc\.m2\repository\com\fasterxml\jackson\core\jackson-databind\2.11.0\jackson-databind-2.11.0.jar;C:\Users\ppc\.m2\repository\com\fasterxml\jackson\core\jackson-annotations\2.11.0\jackson-annotations-2.11.0.jar;C:\Users\ppc\.m2\repository\com\fasterxml\jackson\core\jackson-core\2.11.0\jackson-core-2.11.0.jar;C:\Users\ppc\.m2\repository\com\fasterxml\jackson\datatype\jackson-datatype-jdk8\2.11.0\jackson-datatype-jdk8-2.11.0.jar;C:\Users\ppc\.m2\repository\com\fasterxml\jackson\datatype\jackson-datatype-jsr310\2.11.0\jackson-datatype-jsr310-2.11.0.jar;C:\Users\ppc\.m2\repository\com\fasterxml\jackson\module\jackson-module-parameter-names\2.11.0\jackson-module-parameter-names-2.11.0.jar;C:\Users\ppc\.m2\repository\org\springframework\boot\spring-boot-starter-tomcat\2.3.0.RELEASE\spring-boot-starter-tomcat-2.3.0.RELEASE.jar;C:\Users\ppc\.m2\repository\org\apache\tomcat\embed\tomcat-embed-core\9.0.35\tomcat-embed-core-9.0.35.jar;C:\Users\ppc\.m2\repository\org\glassfish\jakarta.el\3.0.3\jakarta.el-3.0.3.jar;C:\Users\ppc\.m2\repository\org\apache\tomcat\embed\tomcat-embed-websocket\9.0.35\tomcat-embed-websocket-9.0.35.jar;C:\Users\ppc\.m2\repository\org\springframework\spring-web\5.2.6.RELEASE\spring-web-5.2.6.RELEASE.jar;C:\Users\ppc\.m2\repository\org\springframework\spring-beans\5.2.6.RELEASE\spring-beans-5.2.6.RELEASE.jar;C:\Users\ppc\.m2\repository\org\springframework\spring-webmvc\5.2.6.RELEASE\spring-webmvc-5.2.6.RELEASE.jar;C:\Users\ppc\.m2\repository\org\springframework\spring-aop\5.2.6.RELEASE\spring-aop-5.2.6.RELEASE.jar;C:\Users\ppc\.m2\repository\org\springframework\spring-context\5.2.6.RELEASE\spring-context-5.2.6.RELEASE.jar;C:\Users\ppc\.m2\repository\org\springframework\spring-expression\5.2.6.RELEASE\spring-expression-5.2.6.RELEASE.jar;C:\Users\ppc\.m2\repository\org\apache\pdfbox\pdfbox\1.8.16\pdfbox-1.8.16.jar;C:\Users\ppc\.m2\repository\org\apache\pdfbox\fontbox\1.8.16\fontbox-1.8.16.jar;C:\Users\ppc\.m2\repository\org\apache\pdfbox\jempbox\1.8.16\jempbox-1.8.16.jar;C:\Users\ppc\.m2\repository\commons-logging\commons-logging\1.1.1\commons-logging-1.1.1.jar;C:\Users\ppc\.m2\repository\com\itextpdf\itextpdf\5.5.11\itextpdf-5.5.11.jar;C:\Users\ppc\.m2\repository\com\itextpdf\itext-asian\5.2.0\itext-asian-5.2.0.jar;C:\Users\ppc\.m2\repository\org\springframework\boot\spring-boot-starter-test\2.3.0.RELEASE\spring-boot-starter-test-2.3.0.RELEASE.jar;C:\Users\ppc\.m2\repository\org\springframework\boot\spring-boot-test\2.3.0.RELEASE\spring-boot-test-2.3.0.RELEASE.jar;C:\Users\ppc\.m2\repository\org\springframework\boot\spring-boot-test-autoconfigure\2.3.0.RELEASE\spring-boot-test-autoconfigure-2.3.0.RELEASE.jar;C:\Users\ppc\.m2\repository\com\jayway\jsonpath\json-path\2.4.0\json-path-2.4.0.jar;C:\Users\ppc\.m2\repository\net\minidev\json-smart\2.3\json-smart-2.3.jar;C:\Users\ppc\.m2\repository\net\minidev\accessors-smart\1.2\accessors-smart-1.2.jar;C:\Users\ppc\.m2\repository\org\ow2\asm\asm\5.0.4\asm-5.0.4.jar;C:\Users\ppc\.m2\repository\org\slf4j\slf4j-api\1.7.30\slf4j-api-1.7.30.jar;C:\Users\ppc\.m2\repository\jakarta\xml\bind\jakarta.xml.bind-api\2.3.3\jakarta.xml.bind-api-2.3.3.jar;C:\Users\ppc\.m2\repository\jakarta\activation\jakarta.activation-api\1.2.2\jakarta.activation-api-1.2.2.jar;C:\Users\ppc\.m2\repository\org\assertj\assertj-core\3.16.1\assertj-core-3.16.1.jar;C:\Users\ppc\.m2\repository\org\hamcrest\hamcrest\2.2\hamcrest-2.2.jar;C:\Users\ppc\.m2\repository\org\junit\jupiter\junit-jupiter\5.6.2\junit-jupiter-5.6.2.jar;C:\Users\ppc\.m2\repository\org\junit\jupiter\junit-jupiter-api\5.6.2\junit-jupiter-api-5.6.2.jar;C:\Users\ppc\.m2\repository\org\junit\jupiter\junit-jupiter-params\5.6.2\junit-jupiter-params-5.6.2.jar;C:\Users\ppc\.m2\repository\org\junit\jupiter\junit-jupiter-engine\5.6.2\junit-jupiter-engine-5.6.2.jar;C:\Users\ppc\.m2\repository\org\mockito\mockito-core\3.3.3\mockito-core-3.3.3.jar;C:\Users\ppc\.m2\repository\net\bytebuddy\byte-buddy\1.10.10\byte-buddy-1.10.10.jar;C:\Users\ppc\.m2\repository\net\bytebuddy\byte-buddy-agent\1.10.10\byte-buddy-agent-1.10.10.jar;C:\Users\ppc\.m2\repository\org\objenesis\objenesis\2.6\objenesis-2.6.jar;C:\Users\ppc\.m2\repository\org\mockito\mockito-junit-jupiter\3.3.3\mockito-junit-jupiter-3.3.3.jar;C:\Users\ppc\.m2\repository\org\skyscreamer\jsonassert\1.5.0\jsonassert-1.5.0.jar;C:\Users\ppc\.m2\repository\com\vaadin\external\google\android-json\0.0.20131108.vaadin1\android-json-0.0.20131108.vaadin1.jar;C:\Users\ppc\.m2\repository\org\springframework\spring-core\5.2.6.RELEASE\spring-core-5.2.6.RELEASE.jar;C:\Users\ppc\.m2\repository\org\springframework\spring-jcl\5.2.6.RELEASE\spring-jcl-5.2.6.RELEASE.jar;C:\Users\ppc\.m2\repository\org\springframework\spring-test\5.2.6.RELEASE\spring-test-5.2.6.RELEASE.jar;C:\Users\ppc\.m2\repository\org\xmlunit\xmlunit-core\2.7.0\xmlunit-core-2.7.0.jar;C:\Users\ppc\.m2\repository\org\bouncycastle\bcpkix-jdk15on\1.64\bcpkix-jdk15on-1.64.jar;C:\Users\ppc\.m2\repository\org\bouncycastle\bcprov-jdk15on\1.64\bcprov-jdk15on-1.64.jar;C:\Users\ppc\.m2\repository\org\aspectj\aspectjweaver\1.9.5\aspectjweaver-1.9.5.jar" com.intellij.rt.execution.junit.JUnitStarter -ideVersion5 -junit5 com.ppc.spring.SpringTest,test
00:15:08.007 [main] DEBUG org.springframework.context.support.ClassPathXmlApplicationContext - Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@55a1c291
00:15:08.164 [main] DEBUG org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loaded 3 bean definitions from class path resource [springmvc.xml]
00:15:08.192 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'myFactoryBeanProcessor'
*****获取UserController对象*****
00:15:08.206 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'userController'
 UserController 构造函数
*****创建UserService对象*****
UserService 构造函数
*****给userController设置userService属性*****
00:15:08.208 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'myBeanProcessor'
UserController{userService=UserService{}}

Process finished with exit code 0

最后获取的对象UserController的属性userService是有值的

BeanPostProcessor

官方注释

* Factory hook that allows for custom modification of new bean instances &mdash;
 * for example, checking for marker interfaces or wrapping beans with proxies.
 *
 * <p>Typically, post-processors that populate beans via marker interfaces
 * or the like will implement {@link #postProcessBeforeInitialization},
 * while post-processors that wrap beans with proxies will normally
 * implement {@link #postProcessAfterInitialization}.
 *
 * <h3>Registration</h3>
 * <p>An {@code ApplicationContext} can autodetect {@code BeanPostProcessor} beans
 * in its bean definitions and apply those post-processors to any beans subsequently
 * created. A plain {@code BeanFactory} allows for programmatic registration of
 * post-processors, applying them to all beans created through the bean factory.
 *
 * <h3>Ordering</h3>
 * <p>{@code BeanPostProcessor} beans that are autodetected in an
 * {@code ApplicationContext} will be ordered according to
 * {@link org.springframework.core.PriorityOrdered} and
 * {@link org.springframework.core.Ordered} semantics. In contrast,
 * {@code BeanPostProcessor} beans that are registered programmatically with a
 * {@code BeanFactory} will be applied in the order of registration; any ordering
 * semantics expressed through implementing the
 * {@code PriorityOrdered} or {@code Ordered} interface will be ignored for
 * programmatically registered post-processors. Furthermore, the
 * {@link org.springframework.core.annotation.Order @Order} annotation is not
 * taken into account for {@code BeanPostProcessor} beans.

1.允许自定义修改新bean实例&mdash的工厂钩子;*例如,检查标记接口或用代理包装bean。
2.典型地,通过标记接口填充bean的后处理器*或类似的方法将实现{@link #postProcessBeforeInitialization},*而用代理包装bean的后处理器将正常运行*实现{@link #postProcessAfterInitialization}。**
3.注册一个{@code ApplicationContext}可以自动检测{@code BeanPostProcessor} bean*在它的bean定义中,然后将这些后处理程序应用到任何bean*创建。一个普通的{@code BeanFactory}允许编程注册*后处理器,将它们应用到通过bean工厂创建的所有bean。
4.排序*{@code BeanPostProcessor}自动检测到的bean* {@code ApplicationContext}将根据* {@link org.springframework.core。PriorityOrdered},* {@link org.springframework.core。命令}语义。相比之下,通过编程方式注册的bean* {@code BeanFactory}将按注册顺序申请;任何订购的实现所表达的语义* {@code PriorityOrdered}或{@code Ordered}接口将被忽略以编程方式注册后处理器。此外,* {@link org.springframework.core.annotation。Order @Order}注释不是*考虑了{@code BeanPostProcessor} bean。

方法:

/**
	 * Apply this {@code BeanPostProcessor} to the given new bean instance <i>before</i> any bean
	 * initialization callbacks (like InitializingBean's {@code afterPropertiesSet}
	 * or a custom init-method). The bean will already be populated with property values.
	 * The returned bean instance may be a wrapper around the original.
	 * <p>The default implementation returns the given {@code bean} as-is.
	 * @param bean the new bean instance
	 * @param beanName the name of the bean
	 * @return the bean instance to use, either the original or a wrapped one;
	 * if {@code null}, no subsequent BeanPostProcessors will be invoked
	 * @throws org.springframework.beans.BeansException in case of errors
	 * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet
	 */
	@Nullable
	default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}

/ * **将此{@code BeanPostProcessor}应用到给定的新bean实例,先于任何bean*初始化回调(如InitializingBean的{@code afterPropertiesSet})*或自定义的init方法)。bean已经填充了属性值。返回的bean实例可能是原始bean的包装器。默认实现按原样返回给定的{@code bean}。@param bean新bean实例豆子的名字* @返回要使用的bean实例,原始的或包装好的bean实例;*如果{@code null},则不会调用后续的beanpostprocessor* @throws org.springframework.beans。BeansException在错误的情况下* @see org.springframework.beans.factory.InitializingBean # afterPropertiesSet* /

	/**
	 * Apply this {@code BeanPostProcessor} to the given new bean instance <i>after</i> any bean
	 * initialization callbacks (like InitializingBean's {@code afterPropertiesSet}
	 * or a custom init-method). The bean will already be populated with property values.
	 * The returned bean instance may be a wrapper around the original.
	 * <p>In case of a FactoryBean, this callback will be invoked for both the FactoryBean
	 * instance and the objects created by the FactoryBean (as of Spring 2.0). The
	 * post-processor can decide whether to apply to either the FactoryBean or created
	 * objects or both through corresponding {@code bean instanceof FactoryBean} checks.
	 * <p>This callback will also be invoked after a short-circuiting triggered by a
	 * {@link InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation} method,
	 * in contrast to all other {@code BeanPostProcessor} callbacks.
	 * <p>The default implementation returns the given {@code bean} as-is.
	 * @param bean the new bean instance
	 * @param beanName the name of the bean
	 * @return the bean instance to use, either the original or a wrapped one;
	 * if {@code null}, no subsequent BeanPostProcessors will be invoked
	 * @throws org.springframework.beans.BeansException in case of errors
	 * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet
	 * @see org.springframework.beans.factory.FactoryBean
	 */
	@Nullable
	default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}

*将此{@code BeanPostProcessor}应用到给定的新bean实例后的任何bean*初始化回调(如InitializingBean的{@code afterPropertiesSet})*或自定义的init方法)。bean已经填充了属性值。返回的bean实例可能是原始bean的包装器。对于FactoryBean,这个回调将同时为FactoryBean调用实例和由FactoryBean创建的对象(从Spring 2.0开始)。的后处理器可以决定是应用到FactoryBean还是创建的对象或通过相应的{@code bean instanceof FactoryBean}检查两者。这个回调也将在a触发短路后被调用* {@link InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation}方法,*与所有其他{@code BeanPostProcessor}回调相反。默认实现按原样返回给定的{@code bean}。@param bean新bean实例豆子的名字* @返回要使用的bean实例,原始的或包装好的bean实例;*如果{@code null},则不会调用后续的beanpostprocessor* @throws org.springframework.beans。BeansException在错误的情况下* @see org.springframework.beans.factory.InitializingBean # afterPropertiesSet* @see org.springframework.beans.factory.FactoryBean

 

简而言之就是before方法在bean实例化后初始化前使用,after方法在初始化后使用,都可以修改bean对象

Demo:

MyBeanPostProcessor类实现BeanPostProcessor接口,重写两个方法
package com.ppc.spring;

import com.ppc.spring.entity.User;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

public class MyBeanPostProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {

        if(!"user".equals(beanName)) return bean;
        System.out.println("***********MyBeanPostProcessor before processor****************");
        User user = (User)bean;
        user.setName("peter");
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if(!"user".equals(beanName)) return bean;
        System.out.println("***********MyBeanPostProcessor after processor****************");

        User user = (User)bean;
        user.setAge(18);
        return bean;
    }
}

配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">


	<bean id="myBeanProcessor" class="com.ppc.spring.MyBeanPostProcessor"></bean>

	<bean id="user" class="com.ppc.spring.entity.User"></bean>
</beans>

entity

package com.ppc.spring.entity;

public class User {

    private String name;

    private int age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

测试类

package com.ppc.spring;


import com.ppc.spring.controller.UserController;
import com.ppc.spring.entity.User;
import org.junit.jupiter.api.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpringTest {

    @Test
    public void test(){
        ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("springmvc.xml");
        User user = classPathXmlApplicationContext.getBean("user", User.class);
        System.out.println(user);
    }


}

测试结果:

G:\software\jdk\bin\java.exe -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:5452,suspend=y,server=n -ea -Didea.test.cyclic.buffer.size=1048576 -javaagent:C:\Users\ppc\.IntelliJIdea2019.1\system\captureAgent\debugger-agent.jar -Dfile.encoding=UTF-8 -classpath "G:\soft_install\ideaIU\IntelliJ IDEA 2019.1.1\lib\idea_rt.jar;G:\soft_install\ideaIU\IntelliJ IDEA 2019.1.1\plugins\junit\lib\junit-rt.jar;G:\soft_install\ideaIU\IntelliJ IDEA 2019.1.1\plugins\junit\lib\junit5-rt.jar;C:\Users\ppc\.m2\repository\org\junit\platform\junit-platform-launcher\1.6.2\junit-platform-launcher-1.6.2.jar;C:\Users\ppc\.m2\repository\org\apiguardian\apiguardian-api\1.1.0\apiguardian-api-1.1.0.jar;C:\Users\ppc\.m2\repository\org\junit\platform\junit-platform-engine\1.6.2\junit-platform-engine-1.6.2.jar;C:\Users\ppc\.m2\repository\org\opentest4j\opentest4j\1.2.0\opentest4j-1.2.0.jar;C:\Users\ppc\.m2\repository\org\junit\platform\junit-platform-commons\1.6.2\junit-platform-commons-1.6.2.jar;G:\software\jdk\jre\lib\charsets.jar;G:\software\jdk\jre\lib\deploy.jar;G:\software\jdk\jre\lib\ext\access-bridge-64.jar;G:\software\jdk\jre\lib\ext\cldrdata.jar;G:\software\jdk\jre\lib\ext\dnsns.jar;G:\software\jdk\jre\lib\ext\jaccess.jar;G:\software\jdk\jre\lib\ext\jfxrt.jar;G:\software\jdk\jre\lib\ext\localedata.jar;G:\software\jdk\jre\lib\ext\nashorn.jar;G:\software\jdk\jre\lib\ext\sunec.jar;G:\software\jdk\jre\lib\ext\sunjce_provider.jar;G:\software\jdk\jre\lib\ext\sunmscapi.jar;G:\software\jdk\jre\lib\ext\sunpkcs11.jar;G:\software\jdk\jre\lib\ext\zipfs.jar;G:\software\jdk\jre\lib\javaws.jar;G:\software\jdk\jre\lib\jce.jar;G:\software\jdk\jre\lib\jfr.jar;G:\software\jdk\jre\lib\jfxswt.jar;G:\software\jdk\jre\lib\jsse.jar;G:\software\jdk\jre\lib\management-agent.jar;G:\software\jdk\jre\lib\plugin.jar;G:\software\jdk\jre\lib\resources.jar;G:\software\jdk\jre\lib\rt.jar;D:\CODE\MAYUN\spring-source-analysis\target\test-classes;D:\CODE\MAYUN\spring-source-analysis\target\classes;C:\Users\ppc\.m2\repository\org\springframework\boot\spring-boot-starter-web\2.3.0.RELEASE\spring-boot-starter-web-2.3.0.RELEASE.jar;C:\Users\ppc\.m2\repository\org\springframework\boot\spring-boot-starter\2.3.0.RELEASE\spring-boot-starter-2.3.0.RELEASE.jar;C:\Users\ppc\.m2\repository\org\springframework\boot\spring-boot\2.3.0.RELEASE\spring-boot-2.3.0.RELEASE.jar;C:\Users\ppc\.m2\repository\org\springframework\boot\spring-boot-autoconfigure\2.3.0.RELEASE\spring-boot-autoconfigure-2.3.0.RELEASE.jar;C:\Users\ppc\.m2\repository\org\springframework\boot\spring-boot-starter-logging\2.3.0.RELEASE\spring-boot-starter-logging-2.3.0.RELEASE.jar;C:\Users\ppc\.m2\repository\ch\qos\logback\logback-classic\1.2.3\logback-classic-1.2.3.jar;C:\Users\ppc\.m2\repository\ch\qos\logback\logback-core\1.2.3\logback-core-1.2.3.jar;C:\Users\ppc\.m2\repository\org\apache\logging\log4j\log4j-to-slf4j\2.13.2\log4j-to-slf4j-2.13.2.jar;C:\Users\ppc\.m2\repository\org\apache\logging\log4j\log4j-api\2.13.2\log4j-api-2.13.2.jar;C:\Users\ppc\.m2\repository\org\slf4j\jul-to-slf4j\1.7.30\jul-to-slf4j-1.7.30.jar;C:\Users\ppc\.m2\repository\jakarta\annotation\jakarta.annotation-api\1.3.5\jakarta.annotation-api-1.3.5.jar;C:\Users\ppc\.m2\repository\org\yaml\snakeyaml\1.26\snakeyaml-1.26.jar;C:\Users\ppc\.m2\repository\org\springframework\boot\spring-boot-starter-json\2.3.0.RELEASE\spring-boot-starter-json-2.3.0.RELEASE.jar;C:\Users\ppc\.m2\repository\com\fasterxml\jackson\core\jackson-databind\2.11.0\jackson-databind-2.11.0.jar;C:\Users\ppc\.m2\repository\com\fasterxml\jackson\core\jackson-annotations\2.11.0\jackson-annotations-2.11.0.jar;C:\Users\ppc\.m2\repository\com\fasterxml\jackson\core\jackson-core\2.11.0\jackson-core-2.11.0.jar;C:\Users\ppc\.m2\repository\com\fasterxml\jackson\datatype\jackson-datatype-jdk8\2.11.0\jackson-datatype-jdk8-2.11.0.jar;C:\Users\ppc\.m2\repository\com\fasterxml\jackson\datatype\jackson-datatype-jsr310\2.11.0\jackson-datatype-jsr310-2.11.0.jar;C:\Users\ppc\.m2\repository\com\fasterxml\jackson\module\jackson-module-parameter-names\2.11.0\jackson-module-parameter-names-2.11.0.jar;C:\Users\ppc\.m2\repository\org\springframework\boot\spring-boot-starter-tomcat\2.3.0.RELEASE\spring-boot-starter-tomcat-2.3.0.RELEASE.jar;C:\Users\ppc\.m2\repository\org\apache\tomcat\embed\tomcat-embed-core\9.0.35\tomcat-embed-core-9.0.35.jar;C:\Users\ppc\.m2\repository\org\glassfish\jakarta.el\3.0.3\jakarta.el-3.0.3.jar;C:\Users\ppc\.m2\repository\org\apache\tomcat\embed\tomcat-embed-websocket\9.0.35\tomcat-embed-websocket-9.0.35.jar;C:\Users\ppc\.m2\repository\org\springframework\spring-web\5.2.6.RELEASE\spring-web-5.2.6.RELEASE.jar;C:\Users\ppc\.m2\repository\org\springframework\spring-beans\5.2.6.RELEASE\spring-beans-5.2.6.RELEASE.jar;C:\Users\ppc\.m2\repository\org\springframework\spring-webmvc\5.2.6.RELEASE\spring-webmvc-5.2.6.RELEASE.jar;C:\Users\ppc\.m2\repository\org\springframework\spring-aop\5.2.6.RELEASE\spring-aop-5.2.6.RELEASE.jar;C:\Users\ppc\.m2\repository\org\springframework\spring-context\5.2.6.RELEASE\spring-context-5.2.6.RELEASE.jar;C:\Users\ppc\.m2\repository\org\springframework\spring-expression\5.2.6.RELEASE\spring-expression-5.2.6.RELEASE.jar;C:\Users\ppc\.m2\repository\org\apache\pdfbox\pdfbox\1.8.16\pdfbox-1.8.16.jar;C:\Users\ppc\.m2\repository\org\apache\pdfbox\fontbox\1.8.16\fontbox-1.8.16.jar;C:\Users\ppc\.m2\repository\org\apache\pdfbox\jempbox\1.8.16\jempbox-1.8.16.jar;C:\Users\ppc\.m2\repository\commons-logging\commons-logging\1.1.1\commons-logging-1.1.1.jar;C:\Users\ppc\.m2\repository\com\itextpdf\itextpdf\5.5.11\itextpdf-5.5.11.jar;C:\Users\ppc\.m2\repository\com\itextpdf\itext-asian\5.2.0\itext-asian-5.2.0.jar;C:\Users\ppc\.m2\repository\org\springframework\boot\spring-boot-starter-test\2.3.0.RELEASE\spring-boot-starter-test-2.3.0.RELEASE.jar;C:\Users\ppc\.m2\repository\org\springframework\boot\spring-boot-test\2.3.0.RELEASE\spring-boot-test-2.3.0.RELEASE.jar;C:\Users\ppc\.m2\repository\org\springframework\boot\spring-boot-test-autoconfigure\2.3.0.RELEASE\spring-boot-test-autoconfigure-2.3.0.RELEASE.jar;C:\Users\ppc\.m2\repository\com\jayway\jsonpath\json-path\2.4.0\json-path-2.4.0.jar;C:\Users\ppc\.m2\repository\net\minidev\json-smart\2.3\json-smart-2.3.jar;C:\Users\ppc\.m2\repository\net\minidev\accessors-smart\1.2\accessors-smart-1.2.jar;C:\Users\ppc\.m2\repository\org\ow2\asm\asm\5.0.4\asm-5.0.4.jar;C:\Users\ppc\.m2\repository\org\slf4j\slf4j-api\1.7.30\slf4j-api-1.7.30.jar;C:\Users\ppc\.m2\repository\jakarta\xml\bind\jakarta.xml.bind-api\2.3.3\jakarta.xml.bind-api-2.3.3.jar;C:\Users\ppc\.m2\repository\jakarta\activation\jakarta.activation-api\1.2.2\jakarta.activation-api-1.2.2.jar;C:\Users\ppc\.m2\repository\org\assertj\assertj-core\3.16.1\assertj-core-3.16.1.jar;C:\Users\ppc\.m2\repository\org\hamcrest\hamcrest\2.2\hamcrest-2.2.jar;C:\Users\ppc\.m2\repository\org\junit\jupiter\junit-jupiter\5.6.2\junit-jupiter-5.6.2.jar;C:\Users\ppc\.m2\repository\org\junit\jupiter\junit-jupiter-api\5.6.2\junit-jupiter-api-5.6.2.jar;C:\Users\ppc\.m2\repository\org\junit\jupiter\junit-jupiter-params\5.6.2\junit-jupiter-params-5.6.2.jar;C:\Users\ppc\.m2\repository\org\junit\jupiter\junit-jupiter-engine\5.6.2\junit-jupiter-engine-5.6.2.jar;C:\Users\ppc\.m2\repository\org\mockito\mockito-core\3.3.3\mockito-core-3.3.3.jar;C:\Users\ppc\.m2\repository\net\bytebuddy\byte-buddy\1.10.10\byte-buddy-1.10.10.jar;C:\Users\ppc\.m2\repository\net\bytebuddy\byte-buddy-agent\1.10.10\byte-buddy-agent-1.10.10.jar;C:\Users\ppc\.m2\repository\org\objenesis\objenesis\2.6\objenesis-2.6.jar;C:\Users\ppc\.m2\repository\org\mockito\mockito-junit-jupiter\3.3.3\mockito-junit-jupiter-3.3.3.jar;C:\Users\ppc\.m2\repository\org\skyscreamer\jsonassert\1.5.0\jsonassert-1.5.0.jar;C:\Users\ppc\.m2\repository\com\vaadin\external\google\android-json\0.0.20131108.vaadin1\android-json-0.0.20131108.vaadin1.jar;C:\Users\ppc\.m2\repository\org\springframework\spring-core\5.2.6.RELEASE\spring-core-5.2.6.RELEASE.jar;C:\Users\ppc\.m2\repository\org\springframework\spring-jcl\5.2.6.RELEASE\spring-jcl-5.2.6.RELEASE.jar;C:\Users\ppc\.m2\repository\org\springframework\spring-test\5.2.6.RELEASE\spring-test-5.2.6.RELEASE.jar;C:\Users\ppc\.m2\repository\org\xmlunit\xmlunit-core\2.7.0\xmlunit-core-2.7.0.jar;C:\Users\ppc\.m2\repository\org\bouncycastle\bcpkix-jdk15on\1.64\bcpkix-jdk15on-1.64.jar;C:\Users\ppc\.m2\repository\org\bouncycastle\bcprov-jdk15on\1.64\bcprov-jdk15on-1.64.jar;C:\Users\ppc\.m2\repository\org\aspectj\aspectjweaver\1.9.5\aspectjweaver-1.9.5.jar" com.intellij.rt.execution.junit.JUnitStarter -ideVersion5 -junit5 com.ppc.spring.SpringTest
Connected to the target VM, address: '127.0.0.1:5452', transport: 'socket'
19:21:52.855 [main] DEBUG org.springframework.context.support.ClassPathXmlApplicationContext - Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@446293d
19:21:53.007 [main] DEBUG org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loaded 2 bean definitions from class path resource [springmvc.xml]
19:21:53.037 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'myBeanProcessor'
19:21:53.065 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'user'
***********MyBeanPostProcessor before processor****************
***********MyBeanPostProcessor after processor****************
User{name='peter', age=18}
Disconnected from the target VM, address: '127.0.0.1:5452', transport: 'socket'

Process finished with exit code 0

User对象name、age属性都有值,前置处理器、后置处理器赋值处理成功

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值