天天看點

BeanFactoryPostProcessor與BeanPostProcessor

從名稱上不難看出一個是對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,有如下使用場景

BeanFactoryPostProcessor與BeanPostProcessor

CustomerEditorConfigure:幫助我們注冊PropertyEditorSupport,用于最後給bean執行個體指派時使用

PropertyPlaceHolderConfigurer:使用PropertyPlaceholderConfigurer可以在XML配置檔案中加入外部屬性檔案,當然也可以指定外部檔案的編碼。PropertyPlaceholderConfigurer可以将上下文(配置文 件)中的屬性值放在另一個單獨的标準java Properties檔案中去。在XML檔案中用${key}替換指定的properties檔案中的值。這樣的話,隻需要對properties檔案進 行修改,而不用對xml配置檔案進行修改

BeanPostProcessor作用于bean,Spring中對它的應用點如: ApplicationContextAwareProcessor,用于幫我們實作Aware接口的功能

當然還有其他的一些比如ApplicationListenerDetector:用于檢測ApplicationContext的ApplicationListener,監聽ApplicationContext釋出的事件;我們還可以通過它修改bean的屬性等等。