从名称上不难看出一个是对BeanFactory的后置处理另外一个是对Bean的后置处理。在通过ApplicationContext的BeanFactoryPostProcessor支持两种方式的配置,即通过硬编码方式和xml配置文件配置;BeanPostProcessor一般使用xml配置方式注册
BeanFactoryPostProcessor是在ApplicationContext引入的用于处理BeanFactory,定义如下
/**
* 允许自定义修改应用程序上下文的bean定义,调整上下文的基础bean工厂的bean属性值。
*
* <p>应用程序上下文可以在其bean定义中自动检测BeanFactoryPostProcessor bean
* ,并在创建任何其他bean之前应用它们。
*
* BeanFactoryPostProcessor可以与bean定义交互并修改bean定义,但绝不能与bean实例交互。
* 这样做可能会导致bean过早实例化,违反容器并导致意外的副作用。 如果需要bean实例交互,
* 请考虑实现{@link BeanPostProcessor}
*
* @author Juergen Hoeller
* @since 06.07.2003
* @see BeanPostProcessor
* @see PropertyResourceConfigurer
*/
public interface BeanFactoryPostProcessor {
/**
* 在标准初始化之后修改应用程序上下文的内部bean工厂。
* 将加载所有bean定义,但尚未实例化任何bean。 这允许覆盖或添加属性,甚至是初始化bean。
* @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;
}
BeanPostProcessor是BeanFactory引入的用于处理bean
/*
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.beans.factory.config;
import org.springframework.beans.BeansException;
/**
* 工厂钩子,允许自定义修改新的bean实例,例如 检查标记
*
* <p>ApplicationContexts can autodetect BeanPostProcessor beans in their
* bean definitions and apply them to any beans subsequently created.
* Plain bean factories allow for programmatic registration of post-processors,
* applying to all beans created through this factory.
*
* <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}.
*
* @author Juergen Hoeller
* @since 10.10.2003
* @see InstantiationAwareBeanPostProcessor
* @see DestructionAwareBeanPostProcessor
* @see ConfigurableBeanFactory#addBeanPostProcessor
* @see BeanFactoryPostProcessor
*/
public interface BeanPostProcessor {
/**
* 在任何bean初始化回调之前(例如InitializingBean的{@code afterPropertiesSet}或自定义init方法),
* 将此BeanPostProcessor应用于给定的新bean实例。 bean已经填充了属性值。返回的bean实例可能是原始实例的包装器
* @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
*/
Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
/**
* 在</ i>任何bean初始化回调之后(如InitializingBean的{@code afterPropertiesSet}或自定义init方法),
* 将此BeanPostProcessor应用于给定的新bean实例<i>。 bean已经填充了属性值
* 返回的bean实例可能是原始实例的包装器。
* <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.
*
* 对于factorBean,这个回调方法同时会被应用于FactoryBean实例和FactroyBean创建的实例对象
* 后处理器可以通过相应的{@code bean instanceof FactoryBean}检查来决定是应用于FactoryBean还是应用于创建的对象
* 与所有其他BeanPostProcessor回调相反方法,在由{@ linkInstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation}
* 触发的短路之后也将调用此回调
* @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
*/
Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}
BeanFactorPostProcessor用于处理beanFactory,我们可以通过它改变beanFactory的相关属性,并让其作用于beanFactory中的bean,有如下使用场景
CustomerEditorConfigure:帮助我们注册PropertyEditorSupport,用于最后给bean实例赋值时使用
PropertyPlaceHolderConfigurer:使用PropertyPlaceholderConfigurer可以在XML配置文件中加入外部属性文件,当然也可以指定外部文件的编码。PropertyPlaceholderConfigurer可以将上下文(配置文 件)中的属性值放在另一个单独的标准java Properties文件中去。在XML文件中用${key}替换指定的properties文件中的值。这样的话,只需要对properties文件进 行修改,而不用对xml配置文件进行修改
BeanPostProcessor作用于bean,Spring中对它的应用点如: ApplicationContextAwareProcessor,用于帮我们实现Aware接口的功能
当然还有其他的一些比如ApplicationListenerDetector:用于检测ApplicationContext的ApplicationListener,监听ApplicationContext发布的事件;我们还可以通过它修改bean的属性等等。