1. 程式人生 > >Spring的IOC的原始碼解析(二)

Spring的IOC的原始碼解析(二)

在《Spring的IOC的原始碼解析(一)》中完成了BeanDefinition的解析和載入,下邊會接著分析bean的PostProcessor一、準備一些公共的物件邏輯都在這句程式碼中:prepareBeanFactory(beanFactory);主要操作有:設定類載入器,設定EL表示式處理器,編輯器,Aware介面處理器,註冊自動裝配類,設定LTW ware bean的BPP,註冊環境bean這裡一共這設定了3個公共的BPP:ApplicationContextAwareProcessorApplicationListenerDetectorLoadTimeWeaverAwareProcessor二、BFPP的例項化和執行
在BeanDefinition的解析和載入過程中,如果也設定了BFPP bean,這些bean將在這裡例項化和執行// Invoke factory processors registered as beans in the context.invokeBeanFactoryPostProcessors(beanFactory);從bean容器中獲取BFPP BeanDefinition的方法:beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);首先處理的是BeanDefinitionRegistryPostProcessor.class Bean
然後處理,其他BeanFactoryPostProcessor.class Bean beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);BFPP bean例項化的方法是:beanFactory.getBean(ppName, BeanFactoryPostProcessor.class);對每一個BFPP物件,都要執行postProcessBeanFactory方法:postProcessor.postProcessBeanFactory(beanFactory);三、BPP的例項化// Register bean processors that intercept bean creation.
用於在bean的建立過程中,攔截以及AOP代理實現registerBeanPostProcessors(beanFactory);//初始化BPP並註冊到工程中首先,獲取BPP的BeanDefinition:beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);BPP BeanDefinition一般在其他bean標籤的解析過程中設定到容器中;例如<aop:config>會設定嘗試設定AspectJAwareAdvisorAutoProxyCreator例項化的程式碼:beanFactory.getBean(ppName, BeanPostProcessor.class);最後,註冊BPP,這裡註冊就是把BPP物件放到beanFactory的屬性beanPostProcessors中,方便getBean方法中使用;final List<BeanPostProcessor> beanPostProcessors = new ArrayList<>();for (BeanPostProcessor postProcessor : postProcessors) {    beanFactory.addBeanPostProcessor(postProcessor);}注意,在bean容器的初始化過程中,ApplicationContextAwareProcessor,ApplicationListenerDetector,LoadTimeWeaverAwareProcessor這3個BPP是先於所有的BFPP初始化的,但是他們的初始化是主動的,使用Java的new關鍵字。3.初始化non-lazy-init的beanfinishBeanFactoryInitialization(beanFactory);首先,例項化LoadTimeWeaverAware型別的bean,公共的BPP LoadTimeWeaverAwareProcessor會為這些bean 物件設定loadTimeWeaver屬性;loadTimeWeaver屬性的值分析見《load-time-weaver標籤的解析》String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);for (String weaverAwareName : weaverAwareNames) {    getBean(weaverAwareName);}然後,處理non-lazy-init的單例模式bean,非單例模式的bean不用提前註冊。if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {    getBean(beanName);}關於getBean()方法,即bean的例項化過程,參看《Spring的IOC的原始碼解析(三)》。