從名稱上不難看出一個是對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的屬性等等。