Spring源碼解析一:IOC過程源碼解析

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)源碼---結束插件

未完待續。。。代理

相關文章
相關標籤/搜索