IOC的核心就是代碼入口就在AbstractApplictionContextjava
public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // 在刷新容器前進行一些準備工做,例如設置容器的激活狀態,校驗容器環境所必須的啓動參數 prepareRefresh(); // 刷新內部的BeanFactory,得到一個新鮮的BeanFactory,這裏面主要是讀取XML文件,將其轉換爲BeanDefinition ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // 對BeanFactory進行進一步的完善,包括註冊應用上下文感知以及監聽器感知的BeanPostProcessor, // 先註冊一些系統的環境Bean prepareBeanFactory(beanFactory); try { // 給子類在初始化BeanFactory重寫修改變更beanFactory的權利 postProcessBeanFactory(beanFactory); // 調用BeanFactoryPostProcessor,能夠修改beanFactory,與上面不一樣的是,這裏是相似插件的形式,耦合度更低 invokeBeanFactoryPostProcessors(beanFactory); // 提早註冊BeanPostProcessor,用於後期提供代理等功能 registerBeanPostProcessors(beanFactory); // 初始化消息源,用於國際化 initMessageSource(); // 初始化應用事件廣播器,用於廣播應用上下文事件 initApplicationEventMulticaster(); // Initialize other special beans in specific context subclasses. onRefresh(); // 爲應用事件廣播器初始化監聽器(ApplicationListener) registerListeners(); // 實例化並註冊全部非懶加載的bean finishBeanFactoryInitialization(beanFactory); // 刷新容器後的額外工做,初始化生命週期執行器,發佈容器刷新完畢的應用上下文事件 finishRefresh(); } catch (BeansException ex) { if (logger.isWarnEnabled()) { logger.warn("Exception encountered during context initialization - " + "cancelling refresh attempt: " + ex); } // Destroy already created singletons to avoid dangling resources. destroyBeans(); // Reset 'active' flag. cancelRefresh(ex); // Propagate exception to caller. throw ex; } finally { // 清除掉再也不須要的緩存,節省空間 resetCommonCaches(); } } }
---分析一下上面代碼中的invokeBeanFactoryPostProcessors(beanFactory)源碼---開始spring
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) { // 調用全部的BeanFactoryPostProcessors PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors()); // Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime // (e.g. through an @Bean method registered by ConfigurationClassPostProcessor) if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); } }
咱們知道BeanFactoryPostProcessor能夠對已經生成好的BeanDefinition進行修改,也能夠動態的添加來自第三方的BeanDefinition。好比咱們熟知的Mybatis中的Mapper對象。若是咱們使用Spring-Mybatis包中的註解@MapperScan則能夠將咱們定義的mapper對象加入到Spring容器中,便於咱們在項目中注入到指定的地方。緩存
@MapperScan("com.demo") @Configuration public class Configuration(){ } @Service public class Service{ @Autowired private DemoMapper demoMapper; }
public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) { // 存放全部已經調用過的BeanFactoryPostProcessor,避免重複執行 Set<String> processedBeans = new HashSet<String>(); // Spring默認使用的BeanFactory是DefaultListableBeanFactory,其已經實現了BeanDefinitionRegistry接口 if (beanFactory instanceof BeanDefinitionRegistry) { BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory; // 用於存放普通的BeanFactoryPostProcessor List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>(); // 用於存放BeanDefinitionRegistryPostProcessor List<BeanDefinitionRegistryPostProcessor> registryPostProcessors = new LinkedList<BeanDefinitionRegistryPostProcessor>(); /* 執行咱們自定義的beanFactoryPostProcessor,Spring提供customizeContext()方法給予咱們定製化構建 ApplicationContext的機會,因此在這個方法中咱們能夠動態的添加自定義的BeanFactoryPostProcessor。 這裏將普通的BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor區分開分別執行。 */ for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) { if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) { BeanDefinitionRegistryPostProcessor registryPostProcessor = (BeanDefinitionRegistryPostProcessor) postProcessor; registryPostProcessor.postProcessBeanDefinitionRegistry(registry); registryPostProcessors.add(registryPostProcessor); } else { regularPostProcessors.add(postProcessor); } } String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); // 調用實現了PriorityOrdered接口的BeanFactoryPostProcessor List<BeanDefinitionRegistryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>(); for (String ppName : postProcessorNames) { if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); } } // 按照權重排序 sortPostProcessors(beanFactory, priorityOrderedPostProcessors); registryPostProcessors.addAll(priorityOrderedPostProcessors); invokeBeanDefinitionRegistryPostProcessors(priorityOrderedPostProcessors, registry); // 調用實現了 Ordered接口的,步驟跟上面同樣. postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); List<BeanDefinitionRegistryPostProcessor> orderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>(); for (String ppName : postProcessorNames) { if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) { orderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); } } sortPostProcessors(beanFactory, orderedPostProcessors); registryPostProcessors.addAll(orderedPostProcessors); invokeBeanDefinitionRegistryPostProcessors(orderedPostProcessors, registry); // 最後調用其它的BeanFactoryPostProcessor // 若是有BeanDefinitionRegistryPostProcessor被執行, 則有可能會產生新的BeanDefinitionRegistryPostProcessor,所以這邊將reiterate賦值爲true, 表明須要再循環查找一次 boolean reiterate = true; while (reiterate) { reiterate = false; postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); for (String ppName : postProcessorNames) { if (!processedBeans.contains(ppName)) { BeanDefinitionRegistryPostProcessor pp = beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class); registryPostProcessors.add(pp); processedBeans.add(ppName); pp.postProcessBeanDefinitionRegistry(registry); reiterate = true; } } } invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory); invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory); } else { invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory); } /* 上面是經過customizeContext來動態添加BeanPostProcessor,而從這裏的代碼咱們能夠看出,只要咱們寫好一個 BeanFactoryPostProcessor,使用任意方法將其加入到Spring容器中,Spring也能夠解析後執行。這裏足以看出Spring強大的兼容性*/ String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false); List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>(); List<String> orderedPostProcessorNames = new ArrayList<String>(); List<String> nonOrderedPostProcessorNames = new ArrayList<String>(); for (String ppName : postProcessorNames) { if (processedBeans.contains(ppName)) { // 跳過已經執行過的 } else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class)); } else if (beanFactory.isTypeMatch(ppName, Ordered.class)) { orderedPostProcessorNames.add(ppName); } else { nonOrderedPostProcessorNames.add(ppName); } } sortPostProcessors(beanFactory, priorityOrderedPostProcessors); invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory); List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>(); for (String postProcessorName : orderedPostProcessorNames) { orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); } sortPostProcessors(beanFactory, orderedPostProcessors); invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory); List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>(); for (String postProcessorName : nonOrderedPostProcessorNames) { nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); } invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory); // 清空Bean工廠的元數據緩存,由於在BeanFactoryPostProcessor中可能已經更改了BeanDefinition,因此這裏須要清空 beanFactory.clearMetadataCache(); }
這個方法比較長,我我的以爲spring應當將其拆分紅一個個小的方法,使結構更加清晰。app
BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor的子接口,它提供了動態註冊Bean的能力。
咱們最常使用的是它的實現類ConfigurationClassPostProcessor,其帶有一個Bean定義讀取器。這個讀取器可
以讀取@Configuration、@Import、@ImportResource註解標註下的全部Bean定義,並最終添加到Spring的BeanFactory中。post
public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor, PriorityOrdered, ResourceLoaderAware, BeanClassLoaderAware, EnvironmentAware { *** private ConfigurationClassBeanDefinitionReader reader; *** }
不管是在普通的Spring項目亦或是SpringBoot項目,只要咱們開啓了對註解配置的支持,那麼系統就會自動註冊ConfigurationClassPostProcessorthis
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) { /** * 獲取全部的配置定義,注意:此時系統中沒有任何咱們自定義的@Configuration配置定義。 * 但若是是SpringBoot項目,系統默認會將啓動類SpringBootApplication加入到系統配置定義中去。 */ Set<BeanDefinitionHolder> configCandidates = new LinkedHashSet<BeanDefinitionHolder>(); for (String beanName : registry.getBeanDefinitionNames()) { BeanDefinition beanDef = registry.getBeanDefinition(beanName); if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) { configCandidates.add(new BeanDefinitionHolder(beanDef, beanName)); } } // 若是配置類爲空,當即返回 if (configCandidates.isEmpty()) { return; } // 這裏初始化一些生成器 SingletonBeanRegistry singletonRegistry = null; if (registry instanceof SingletonBeanRegistry) { singletonRegistry = (SingletonBeanRegistry) registry; if (!this.localBeanNameGeneratorSet && singletonRegistry.containsSingleton(CONFIGURATION_BEAN_NAME_GENERATOR)) { BeanNameGenerator generator = (BeanNameGenerator) singletonRegistry.getSingleton(CONFIGURATION_BEAN_NAME_GENERATOR); this.componentScanBeanNameGenerator = generator; this.importBeanNameGenerator = generator; } } // 遞歸解析每個@Configuration配置類 ConfigurationClassParser parser = new ConfigurationClassParser( this.metadataReaderFactory, this.problemReporter, this.environment, this.resourceLoader, this.componentScanBeanNameGenerator, registry); for (BeanDefinitionHolder holder : configCandidates) { BeanDefinition bd = holder.getBeanDefinition(); try { if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) bd).hasBeanClass()) { parser.parse(((AbstractBeanDefinition) bd).getBeanClass(), holder.getBeanName()); } else { parser.parse(bd.getBeanClassName(), holder.getBeanName()); } } catch (IOException ex) { throw new BeanDefinitionStoreException("Failed to load bean class: " + bd.getBeanClassName(), ex); } } /** * 校驗解析出的全部@Configuration配置類,例如若是是@Configuration註解標註的full配置類,那麼類不能被聲明爲final,不然報錯。由於Spring會爲 * 每個@Configuration配置類建立一個CGLIB代理,咱們知道CGLIB是經過繼承關係來實現代理的,既然用到繼承,其父類確定不能爲final。 */ parser.validate(); // 處理@PropertySource註解的配置類 Stack<PropertySource<?>> parsedPropertySources = parser.getPropertySources(); if (!parsedPropertySources.isEmpty()) { if (!(this.environment instanceof ConfigurableEnvironment)) { logger.warn("Ignoring @PropertySource annotations. " + "Reason: Environment must implement ConfigurableEnvironment"); } else { MutablePropertySources envPropertySources = ((ConfigurableEnvironment)this.environment).getPropertySources(); while (!parsedPropertySources.isEmpty()) { envPropertySources.addLast(parsedPropertySources.pop()); } } } /* 讀取每個@Configuration配置類中定義的bean,加入到ioc容器中。包括使用@Bean註解標註的方法,@Import導入的registry註冊器, * @ImportResource導入的xml資源 */ if (this.reader == null) { this.reader = new ConfigurationClassBeanDefinitionReader( registry, this.sourceExtractor, this.problemReporter, this.metadataReaderFactory, this.resourceLoader, this.environment, this.importBeanNameGenerator); } this.reader.loadBeanDefinitions(parser.getConfigurationClasses()); // Register the ImportRegistry as a bean in order to support ImportAware @Configuration classes if (singletonRegistry != null) { if (!singletonRegistry.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) { singletonRegistry.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry()); } } }
---分析一下上面代碼中的invokeBeanFactoryPostProcessors(beanFactory)源碼---結束插件
未完待續。。。代理