概述:
BeanPostProcessor接口是眾多Spring提供給開發者的bean生命周期內自定義邏輯拓展接口中的一個,其他還有類似InitializingBean,DisposableBean,BeanFactoryAware等。
實現了BeanPostProcessor接口的Bean我們叫做后處理器。
BeanPostProcessor接口定義如下
:
<span style="font-size:14px;">public interface BeanPostProcessor { Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException; Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException; }</span>
在項目中(假設只有一個Spring容器),我們如果定義了一個實現了BeanPostProcessor接口的Bean(后處理器),那么在這個Bean所在的容器中的其他所有Bean在初始化前都會執行后處理器的postProcessBeforeInitialization方法,在初始化后都會執行后處理器的postProcessAfterInitialization方法。具體執行順序是:
1. BeanPostProcessor.postProcessBeforeInitialization
2. InitializingBean.afterPropertiesSet
3. bean配置中的init-method
4. BeanPostProcessor.postProcessAfterInitialization
關於bean生命周期可以參考這里。
一個容器中可以定義多個后處理器,那么該容器內其他素有Bean初始化前后就會依次執行這些Bean的postProcessBeforeInitialization方法和postProcessAfterInitialization方法。
后處理器的配置方式和普通的Spring Bean是一樣的。
下面我們來看一個Spring的例子:
類定義:
package scripting; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.beans.BeansException; public class InstantiationTracingBeanPostProcessor implements BeanPostProcessor { // simply return the instantiated bean as-is public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { return bean; // we could potentially return any object reference here... } public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("Bean '" + beanName + "' created : " + bean.toString()); return bean; } }
spring配置:
<?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:lang="http://www.springframework.org/schema/lang" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang.xsd"> <lang:groovy id="messenger" script-source="classpath:org/springframework/scripting/groovy/Messenger.groovy"> <lang:property name="message" value="Fiona Apple Is Just So Dreamy."/> </lang:groovy> <!-- when the above bean (messenger) is instantiated, this custom BeanPostProcessor implementation will output the fact to the system console --> <bean class="scripting.InstantiationTracingBeanPostProcessor"/> </beans>
寫一個main方法啟動Spring容器:
import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.scripting.Messenger; public final class Boot { public static void main(final String[] args) throws Exception { ApplicationContext ctx = new ClassPathXmlApplicationContext("scripting/beans.xml"); Messenger messenger = (Messenger) ctx.getBean("messenger"); System.out.println(messenger); } }
執行后,打印結果如下:
Bean 'messenger' created : org.springframework.scripting.groovy.GroovyMessenger@272961
org.springframework.scripting.groovy.GroovyMessenger@272961
在配置中,實現了BeanPostProcessor接口的Bean(后處理器)會優先被Spring容器實例化,以便在后續實例化其他Bean的時候能起作用。