概述:
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的時候能起作用。
