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維修中心
※聚甘新