javascript
Spring中的后置处理器BeanPostProcessor讲解
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;} } View Codespring容器中配置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{@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {if (bean instanceof Cat) {//輸出原始屬性Cat cat = (Cat) bean;cat.say();return bean;}return bean;}@Overridepublic 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";} }觀察結果:
容器啟動時,輸出:
name:HelloKitty age:1 訪問項目http://localhost:8080/demo/index,index鏈接時,輸出: name:hello maomi age:3 -------------------------------------------------------------------------------------------------------------------------- 可以看到通過后處理器處理過后的bean信息已經改變。最后,看看源碼中如何調用自定義實現的。 在初始化bean方法中:AbstractAutowireCapableBeanFactory.java /*** 初始化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; }?
轉載于:https://www.cnblogs.com/tenWood/p/8542521.html
總結
以上是生活随笔為你收集整理的Spring中的后置处理器BeanPostProcessor讲解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 掌上生活app是干嘛的
- 下一篇: 微博钱包如何提前结清(新浪博客的微博)