Spring中提供了很多PostProcessor供開發者進行拓展,例如:BeanPostProcessor、BeanFactoryPostProcessor、BeanValidationPostProcessor等一系列后處理器。他們的使用方式大多類似,了解其中一個並掌握他的使用方式,其他的可以觸類旁通。
BeanPostProcessor接口作用:
如果我們想在Spring容器中完成bean實例化、配置以及其他初始化方法前后要添加一些自己邏輯處理。我們需要定義一個或多個BeanPostProcessor接口實現類,然后注冊到Spring IoC容器中。
BeanPostProcessor API:
public interface BeanPostProcessor { /** * Apply this BeanPostProcessor to the given new bean instance <i>before</i> any bean * initialization callbacks (like InitializingBean's {@code afterPropertiesSet} * or a custom init-method). The bean will already be populated with property values. */ //實例化、依賴注入完畢,在調用顯示的初始化之前完成一些定制的初始化任務 Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException; /** * Apply this BeanPostProcessor to the given new bean instance <i>after</i> any bean * initialization callbacks (like InitializingBean's {@code afterPropertiesSet} * or a custom init-method). The bean will already be populated with property values. */ //實例化、依賴注入、初始化完畢時執行 Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException; }
BeanPostProcessor接口提供了兩個供開發者自定義的方法:postProcessBeforeInitialization、postProcessAfterInitialization。
postProcessBeforeInitialization:該方法主要針對spring在bean初始化時調用初始化方法前進行自定義處理。
postProcessAfterInitialization:該方法主要針對spring在bean初始化時調用初始化方法后進行自定義處理。
測試代碼:
com.test.model.Cat:

package com.test.model; /** * 測試bean */ public class Cat { private String name; private int age; public void say() { System.out.println("name:" + name); System.out.println("age:" + age); } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
spring容器中配置cat,和cat的beanPostProcessor:
<!--配置bean並初始化--> <bean id="cat" class="com.test.model.Cat" > <property name="name" value="HelloKitty" /> <property name="age" value="1" /> </bean> <bean id="catBeanPostProcessor" class="com.test.postprocessor.CatBeanPostProcessor" />
com.test.postprocessor.CatBeanPostProcessor:
package com.test.postprocessor; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; import com.test.model.Cat; /** * 自定義后處理器 */ public class CatBeanPostProcessor implements BeanPostProcessor{ @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if (bean instanceof Cat) { //輸出原始屬性 Cat cat = (Cat) bean; cat.say(); return bean; } return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if (bean instanceof Cat) { //修改屬性值,並返回 Cat cat = (Cat) bean; cat.setName("hello maomi"); cat.setAge(3); return cat; } return bean; } }
IndexController:
package com.cy.controller; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import org.springframework.context.ApplicationContext; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.context.support.WebApplicationContextUtils; import com.test.model.Cat; @Controller public class IndexController { //到index首頁 @RequestMapping(value="index") public String index(HttpServletRequest request){ /** * 訪問index同時,從容器中獲取已經被初始化之后處理過的cat,打印信息 */ ServletContext servletContext = request.getSession().getServletContext(); ApplicationContext ac = WebApplicationContextUtils.getWebApplicationContext(servletContext); Cat c = (Cat) ac.getBean("cat"); c.say(); return "index"; } }
觀察結果:
容器啟動時,輸出:
/** * 初始化bean */ protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) { //省略部分無關代碼 Object wrappedBean = bean; //初始化前 if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } try { //調用初始化方法初始化bean invokeInitMethods(beanName, wrappedBean, mbd); } catch (Throwable ex) { throw new BeanCreationException( (mbd != null ? mbd.getResourceDescription() : null), beanName, "Invocation of init method failed", ex); } //初始化后 if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; } //postProcessBeforeInitialization方法調用 @Override public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) { //調用自定義postProcessBeforeInitialization方法 Object current = beanProcessor.postProcessBeforeInitialization(result, beanName); if (current == null) { return result; } result = current; } return result; } //postProcessAfterInitialization方法調用 @Override public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) { //自定義postProcessAfterInitialization方法調用 Object current = beanProcessor.postProcessAfterInitialization(result, beanName); if (current == null) { return result; } result = current; } return result; }