BeanPostProcessor是處理bean的後置接口,beanDefinitionMaps中的BeanDefinition實例化完成后,完成populateBean,屬性設置,完成
初始化后,這個接口支持對bean做自定義的操作。
一:BeanPostProcessor的使用
定義一個測試用的model對象,name屬性默認為hello
public class BeanDemo {
private String name = "hello";
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
final StringBuffer sb = new StringBuffer("BeanDemo{");
sb.append("name='").append(name).append('\'');
sb.append('}');
return sb.toString();
}
}
自定義一個MyBeanPostProcessor類,實現BeanPostProcessor接口
@Service
public class MyBeanPostProcessor implements BeanPostProcessor {
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return null;
}
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if(beanName.equals("beanDemo")){
BeanDemo beanDemo = (BeanDemo)bean;
beanDemo.setName("kitty");
return beanDemo;
}
return bean;
}
}
從運行結果看,spring中維護的beanName為beanDemo的對象,name屬性為ketty
二:看看源碼怎麼實現的
1:實例化並且註冊到beanPostProcessors集合中
主要的實例化邏輯在這個接口,這個接口的作用就是把所有實現BeanPostProcessor接口的類實例化,然後註冊到 beanPostProcessors這個緩存中
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
// 獲取所有實現接口BeanPostProcessor的beanName
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
// Register BeanPostProcessorChecker that logs an info message when
// a bean is created during BeanPostProcessor instantiation, i.e. when
// a bean is not eligible for getting processed by all BeanPostProcessors.
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
// Separate between BeanPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
/**
* 把實現PriorityOrdered 和 Ordered 和 其他的處理器分開
*/
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
/**
* 1:遍歷集合postProcessorNames
* 2:判斷類型,如果是PriorityOrdered,則實例化對象放入priorityOrderedPostProcessors集合,
* Ordered 則放入orderedPostProcessorNames集合,其他的放入nonOrderedPostProcessorNames集合
*/
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
priorityOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// First, register the BeanPostProcessors that implement PriorityOrdered.
// 首先對priorityOrderedPostProcessors集合中實例對象排序,然後註冊,放入beanFactory中緩存下來
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
// Next, register the BeanPostProcessors that implement Ordered.
// 然後再實例化實現Ordered接口的對象,完成註冊
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
for (String ppName : orderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
sortPostProcessors(orderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
// Now, register all regular BeanPostProcessors.
// 最後實例化什麼都沒有實現的,完成實例化並註冊
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
for (String ppName : nonOrderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
// Finally, re-register all internal BeanPostProcessors.
// 最後再次註冊內部postProcessor
sortPostProcessors(internalPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, internalPostProcessors);
// Re-register post-processor for detecting inner beans as ApplicationListeners,
// moving it to the end of the processor chain (for picking up proxies etc).
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
定義四類容器,高優先級有序、有序、無序、內部
分類放入四種容器:
註冊BeanPostProcessor,將實現BeanPostProcessor接口的對象放入beanPostProcessors緩存中
註冊完PriorityOrdered的實現類后,再處理Ordered的實現類
註冊什麼都沒有實現的BeanPostProcessor接口實現類,
最後註冊內部的BeanPostProcessor對象
到這裏BeanPostProcessor的實例化以及註冊工作完成,在beanFactory的beanPostProcessors集合中已經緩存了所有的beanPostProcessor的對象
2:BeanPostProcessor的使用
因為這個接口是bean的後置接口,所以需要bean創建並初始化完成,才可以發揮作用,上一步的緩存只是埋好點,以備使用,因為bean的實例化流程我們
還沒有分析,這裏直接看一下怎麼使用的
我們看一下init方法后的攔截,因為這個時候已經init完成,可以在後置接口中對bean做一下修改的操作
調用到我們自定義的MyBeanPostProcessor實現類:
把這個beanDemo對象屬性修改一下,修改完,再返回,將這個對象緩存到spring的一級緩存中。
總結:
BeanPostProcessor接口主要是對bean對象做一些自定義的操作,修改bean對象的信息,aop代理也是通過這種方式實現的,
在refresh的registryBeanPostProcessor方法中實例化BeanPostProcessor對象,並且註冊到beanFactory容器的beanPostProcessors的緩存中,
然後在後續的操作中攔截使用。
本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理
【其他文章推薦】
※為什麼 USB CONNECTOR 是電子產業重要的元件?
※網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!
※台北網頁設計公司全省服務真心推薦
※想知道最厲害的網頁設計公司“嚨底家”!
※推薦評價好的iphone維修中心
※聚甘新
