Spring BeanPostProcessor接口使用詳解
Spring中提供了很多PostProcessor供開發(fā)者進行拓展,例如:BeanPostProcessor、BeanFactoryPostProcessor、BeanValidationPostProcessor等一系列后處理器。他們的使用方式大多類似,了解其中一個并掌握他的使用方式,其他的可以觸類旁通。
這里以BeanPostProcessor為例展示其使用方式。
BeanPostProcessor接口提供了兩個供開發(fā)者自定義的方法:postProcessBeforeInitialization、postProcessAfterInitialization。
postProcessBeforeInitialization:該方法主要針對spring在bean初始化時調(diào)用初始化方法前進行自定義處理。
postProcessAfterInitialization:該方法主要針對spring在bean初始化時調(diào)用初始化方法后進行自定義處理。
示例代碼:
/** * 測試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; } }
/** * 自定義后處理器 */ public class CatBeanPostProcessor implements BeanPostProcessor { @Nullable @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if (bean instanceof Cat) { //輸出原始屬性 Cat cat = (Cat) bean; cat.say(); return bean; } return bean; } @Nullable @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; } }
/** * 運行 */ public class Run { public static void main(String[] args) { ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-bean.xml"); Cat cat = (Cat) applicationContext.getBean("cat"); cat.say(); } }
xml配置信息
<!--配置bean并初始化--> <bean id="cat" class="com.source.postprocessor.Cat" > <property name="name" value="HelloKitty" /> <property name="age" value="1" /> </bean> <bean id="catBeanPostProcessor" class="com.source.postprocessor.CatBeanPostProcessor" />
輸出結(jié)果:
name:HelloKitty
age:1
name:hello maomi
age:3
可以看到通過后處理器處理過后的bean信息已經(jīng)改變。最后,看看源碼中如何調(diào)用自定義實現(xiàn)的。
在初始化bean方法中:AbstractAutowireCapableBeanFactory.java
/** * 初始化bean */ protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) { //省略部分無關(guān)代碼 Object wrappedBean = bean; //初始化前 if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } try { //調(diào)用初始化方法初始化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方法調(diào)用 @Override public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) { //調(diào)用自定義postProcessBeforeInitialization方法 Object current = beanProcessor.postProcessBeforeInitialization(result, beanName); if (current == null) { return result; } result = current; } return result; } //postProcessAfterInitialization方法調(diào)用 @Override public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) { //自定義postProcessAfterInitialization方法調(diào)用 Object current = beanProcessor.postProcessAfterInitialization(result, beanName); if (current == null) { return result; } result = current; } return result; }
以上就是spring對自定義方法實現(xiàn)的調(diào)用過程。希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Spring?BeanPostProcessor后處理器源碼解析
- 關(guān)于Spring BeanPostProcessor的執(zhí)行順序
- Spring BeanPostProcessor(后置處理器)的用法
- SpringBoot之通過BeanPostProcessor動態(tài)注入ID生成器案例詳解
- Spring容器的創(chuàng)建過程之如何注冊BeanPostProcessor詳解
- 詳解使用Spring的BeanPostProcessor優(yōu)雅的實現(xiàn)工廠模式
- Spring中的后置處理器BeanPostProcessor詳解
- 解析Java的Spring框架的BeanPostProcessor發(fā)布處理器
- spring中BeanPostProcessor的作用和使用注意事項
相關(guān)文章
java中StringBuffer的length()和capacity()方法對比
這篇文章主要介紹了java中StringBuffer的length()和capacity()方法對比,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-07-07HotSpot的Java對象模型之Oop-Klass模型詳解
這篇文章主要介紹了HotSpot的Java對象模型之Oop-Klass模型詳解,在JVM層面,不僅Java類是對象,Java 方法也是對象, 字節(jié)碼常量池也是對象,一切皆是對象,JVM使用不同的oop-klass模型來表示各種不同的對象,需要的朋友可以參考下2023-08-08SpringBoot同一接口多個實現(xiàn)類配置的實例詳解
這篇文章主要介紹了SpringBoot同一接口多個實現(xiàn)類配置的實例詳解,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-11-11Springboot整合EasyExcel實現(xiàn)Excel文件上傳方式
這篇文章主要介紹了Springboot整合EasyExcel實現(xiàn)Excel文件上傳方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-07-07使用Java的Spring框架編寫第一個程序Hellow world
這篇文章主要介紹了Java的Spring框架并用其開始編寫第一個程序Hellow world的方法,Spring是Java的SSH三大web開發(fā)框架之一,需要的朋友可以參考下2015-12-12Java中隊列Queue和Deque的區(qū)別與代碼實例
學(xué)過數(shù)據(jù)結(jié)構(gòu)的,一定對隊列不陌生,java也實現(xiàn)了隊列,下面這篇文章主要給大家介紹了關(guān)于Java中隊列Queue和Deque區(qū)別的相關(guān)資料,需要的朋友可以參考下2021-08-08Java使用跳轉(zhuǎn)結(jié)構(gòu)實現(xiàn)隊列和棧流程詳解
這篇文章主要介紹了Java使用跳轉(zhuǎn)結(jié)構(gòu)實現(xiàn)隊列和棧流程,連續(xù)結(jié)構(gòu)和跳轉(zhuǎn)結(jié)構(gòu)是數(shù)據(jù)結(jié)構(gòu)中常見的兩種基本數(shù)據(jù)結(jié)構(gòu),而我們本次的主角棧和隊列都 既可以使用使用跳轉(zhuǎn)結(jié)構(gòu)實現(xiàn)也可以使用連續(xù)結(jié)構(gòu)實現(xiàn)2023-04-04