BeanPostProcessor 接口定義回調(diào)方法,你可以實(shí)現(xiàn)該方法來提供自己的實(shí)例化邏輯,依賴解析邏輯等。你也可以在 Spring 容器通過插入一個(gè)或多個(gè) BeanPostProcessor 的實(shí)現(xiàn)來完成實(shí)例化,配置和初始化一個(gè)bean之后實(shí)現(xiàn)一些自定義邏輯回調(diào)方法。
你可以配置多個(gè) BeanPostProcesso r接口,通過設(shè)置 BeanPostProcessor 實(shí)現(xiàn)的 Ordered 接口提供的 order 屬性來控制這些 BeanPostProcessor 接口的執(zhí)行順序。
BeanPostProcessor 可以對(duì) bean(或?qū)ο螅?shí)例進(jìn)行操作,這意味著 Spring IoC 容器實(shí)例化一個(gè) bean 實(shí)例,然后 BeanPostProcessor 接口進(jìn)行它們的工作。
ApplicationContext 會(huì)自動(dòng)檢測(cè)由 BeanPostProcessor 接口的實(shí)現(xiàn)定義的 bean,注冊(cè)這些 bean 為后置處理器,然后通過在容器中創(chuàng)建 bean,在適當(dāng)?shù)臅r(shí)候調(diào)用它。
下面的例子顯示如何在 ApplicationContext 的上下文中編寫,注冊(cè)和使用 BeanPostProcessor。
我們?cè)谶m當(dāng)?shù)奈恢檬褂?Eclipse IDE,然后按照下面的步驟來創(chuàng)建一個(gè) Spring 應(yīng)用程序:
步驟 | 描述 |
---|---|
1 | 創(chuàng)建一個(gè)名稱為 SpringExample 的項(xiàng)目,并且在創(chuàng)建項(xiàng)目的 src 文件夾中創(chuàng)建一個(gè)包 com.tutorialspoint。 |
2 | 使用 Add External JARs 選項(xiàng),添加所需的 Spring 庫,解釋見 Spring Hello World Example 章節(jié)。 |
3 | 在 com.tutorialspoint 包中創(chuàng)建 Java 類 HelloWorld、InitHelloWorld 和 MainApp。 |
4 | 在 src 文件夾中創(chuàng)建 Beans 配置文件 Beans.xml。 |
5 | 最后一步是創(chuàng)建的所有 Java 文件和 Bean 配置文件的內(nèi)容,并運(yùn)行應(yīng)用程序,解釋如下所示。 |
這里是 HelloWorld.java 文件的內(nèi)容:
package com.tutorialspoint;
public class HelloWorld {
private String message;
public void setMessage(String message){
this.message = message;
}
public void getMessage(){
System.out.println("Your Message : " + message);
}
public void init(){
System.out.println("Bean is going through init.");
}
public void destroy(){
System.out.println("Bean will destroy now.");
}
}
這是實(shí)現(xiàn) BeanPostProcessor 的非常簡單的例子,它在任何 bean 的初始化的之前和之后輸入該 bean 的名稱。你可以在初始化 bean 的之前和之后實(shí)現(xiàn)更復(fù)雜的邏輯,因?yàn)槟阌袃蓚€(gè)訪問內(nèi)置 bean 對(duì)象的后置處理程序的方法。
這里是 InitHelloWorld.java 文件的內(nèi)容:
package com.tutorialspoint;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.BeansException;
public class InitHelloWorld implements BeanPostProcessor {
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("BeforeInitialization : " + beanName);
return bean; // you can return any other object as well
}
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("AfterInitialization : " + beanName);
return bean; // you can return any other object as well
}
}
下面是 MainApp.java 文件的內(nèi)容。在這里,你需要注冊(cè)一個(gè)在 AbstractApplicationContext 類中聲明的關(guān)閉 hook 的 registerShutdownHook() 方法。它將確保正常關(guān)閉,并且調(diào)用相關(guān)的 destroy 方法。
package com.tutorialspoint;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApp {
public static void main(String[] args) {
AbstractApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
HelloWorld obj = (HelloWorld) context.getBean("helloWorld");
obj.getMessage();
context.registerShutdownHook();
}
}
下面是 init 和 destroy 方法需要的配置文件 Beans.xml 文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="helloWorld" class="com.tutorialspoint.HelloWorld"
init-method="init" destroy-method="destroy">
<property name="message" value="Hello World!"/>
</bean>
<bean class="com.tutorialspoint.InitHelloWorld" />
</beans>
一旦你創(chuàng)建源代碼和 bean 配置文件完成后,我們就可以運(yùn)行該應(yīng)用程序。如果你的應(yīng)用程序一切都正常,將輸出以下信息:
BeforeInitialization : helloWorld
Bean is going through init.
AfterInitialization : helloWorld
Your Message : Hello World!
Bean will destroy now.