Spring源碼分析專題系列

 
系列文章 前言介紹

本篇文章篇幅較大,但願讀者能夠慢慢閱讀,建議收藏,分屢次閱讀學習。java

  • 學習源碼的過程中,有幾點建議:spring

    • 必定要學會抓重點,概括核心類、核心方法、核心步驟;設計模式

    • 分析源碼咱們不須要太過於糾結細節,否則,這個源碼最起碼得分析月才能分析完;緩存

    • 主要的目的是分析整個容器初始化過程,怎麼初始化bean,怎麼設置動態代理;咱們主要學習的是他們的思想,以及代碼中運用到的設計模式;app

容器框架重要對象
  • BeanFactory:用於訪問容器中bean的接口,使用的是工廠模式,重點注意DefaultListableBeanFactory,是貫穿的整個容器的基本工廠類。框架

  • BeanDefinition:BeanDefinition是bean在Spring中的描述,先讀取到bean的各類元素,而後利用BeanDefinition去初始化bean,是spring從起管理bean對象的數據模型。編輯器

  • BeanDefinitionRegistry接口:註冊bean定義到Spring容器中,與BeanFactory接口相對應,主要針對於Bean的註冊,BeanFactory主要針對於bean對象的管理。ide

  • BeanFactoryPostProcessor接口:bean工廠後置處理器,該接口的做用主要是提供擴展點,用於各類bean定義的註冊和實例化等,比較須要主要關注ConfigurationClassPostProcessor該類;函數

  • BeanPostProcessor接口:bean的後置處理器,該接口提供的擴展點,用於初始化bean,以及初始化完成後的各類擴展;源碼分析

IOC容器初始化的大體流程
  • 首先讀取BeanDefinition放到容器中。

  • 經過BeanFactoryPostProcessor對象的擴展

  • 經過BeanPostProcessor對象的擴展

  • 而後根據BeanDefinition去初始化bean。

  • 最後實際進行初始化而後保存到容器中。

來實現各類不一樣的功能;IOC容器初始化大體的一個流程,主要是看AnnotationConfigApplicationContext和refresh

AnnotationConfigApplicationContext構造器分析

傳入配置類的構造函數

public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
    //初始化容器,建立bean工廠,加載各類內部重要類的bean定義,用於初始化咱們或者其餘引入類
    this();
    //註冊咱們配置類的bean定義,初始化容器,從這個類開始
    register(componentClasses);
    //準備工做作好後,開始初始化容器
    refresh();
}

先看下this()這一行代碼

AnnotatedBeanDefinitionReader:主要用於讀取相關內部的Spring容器的Bean對象。

public AnnotationConfigApplicationContext() {
    //初始化讀取bean定義的讀取器,完成Spring內部bean定義的註冊
    this.reader = new AnnotatedBeanDefinitionReader(this);
    //初始化一個類掃描器,其實這個方法進來,是沒有用到這個掃描器的
    this.scanner = new ClassPathBeanDefinitionScanner(this);
}

從上面建立bean定義讀取器,看下構造方法

//從上面建立bean定義讀取器,看下構造方法
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
    this(registry, getOrCreateEnvironment(registry));
}

public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
    Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
    Assert.notNull(environment, "Environment must not be null");
    //把ApplicationContext對象賦值給bean定義讀取器
    this.registry = registry;
    this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
    //主要是看這個方法,註冊Spring內部重要的bean定義
    AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}

到這裏this(),這個方法流程就過完了,主要就是註冊spring內部重要的bean定義,來看下register(componentClasses)方法

//此目的主要針對於上面註冊的reader進行註冊相關的bean
public void register(Class<?>... annotatedClasses) {
    Assert.notEmpty(annotatedClasses, "At least one annotated class must be specified");
    //使用上面初始化的bean定義讀取器,去註冊咱們配置類的bean定義
    this.reader.register(annotatedClasses);
}
//遍歷去註冊傳入進來的註解相關的Bean對象
public void register(Class<?>... annotatedClasses) {
    for (Class<?> annotatedClass : annotatedClasses) {
        registerBean(annotatedClass);
    }
}
// 
public void registerBean(Class<?> annotatedClass) {
    doRegisterBean(annotatedClass, null, null, null);
}
//註冊bean定義
private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
        @Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
        @Nullable BeanDefinitionCustomizer[] customizers) {
    //根據配置類建立一個bean定義
    AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
    if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
        return;
    }
    abd.setInstanceSupplier(supplier);
    //解析bean的做用域,若是沒有設置,則默認是單例
    ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
    abd.setScope(scopeMetadata.getScopeName());
	// 建立bean對象的bean名稱
    String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
    //解析該bean是否有Lazy,Primary,DependsOn,Description等註解,有則填充進去
    AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
    if (qualifiers != null) {
        for (Class<? extends Annotation> qualifier : qualifiers) {
			//判斷是不是Primary
            if (Primary.class == qualifier) {
                abd.setPrimary(true);
            }
			// 判斷是否屬於懶惰加載
            else if (Lazy.class == qualifier) {
                abd.setLazyInit(true);
            }
            else {
                abd.addQualifier(new AutowireCandidateQualifier(qualifier));
            }
        }
    }
    if (customizers != null) {
        for (BeanDefinitionCustomizer customizer : customizers) {
            customizer.customize(abd);
        }
    }
	// 構建BeanDefinitionHolder對象去引用對象
    BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
    definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
    //最後把該bean定義註冊到Bean工廠中去
    BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}

register(componentClasses),方法到此結束,而後咱們分析refresh();方法,該方法初始化了IOC容器。

public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
        //設置容器狀態,準備刷新容器
        prepareRefresh();
        //獲取到容器的bean工廠
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
        //填充bean工廠的各類屬性
        prepareBeanFactory(beanFactory);
        try {
            //留給子類實現,咱們看的AnnotationConfigApplicationContext繼承了GenericApplicationContext,該類主要是註冊了ServletContextAwareProcessor
            postProcessBeanFactory(beanFactory);
            //主要調用bean工廠的後置處理器,把咱們的類,註冊成bean定義
            invokeBeanFactoryPostProcessors(beanFactory);
			  // 註冊 BeanPostProcessor 的實現類
         // 此接口兩個方法: postProcessBeforeInitialization 和 postProcessAfterInitialization
         // 兩個方法分別在 Bean 初始化以前和初始化以後獲得執行。注意,到這裏 Bean 還沒初始化
            registerBeanPostProcessors(beanFactory);
            //初始化國際化資源(這個方法不重要)
            initMessageSource();
            //Spring事件相關,主要是建立一個事件多播器
            initApplicationEventMulticaster();
            //留給子類實現
            onRefresh();
            //把咱們的事件註冊到容器中
            registerListeners();
            //實例化咱們須要的bean,放入IOC容器
            finishBeanFactoryInitialization(beanFactory);
            //完成容器IOC容器初始化,而且發佈初始化完成事件
            finishRefresh();
        }
        catch (BeansException ex) {
            if (logger.isWarnEnabled()) {
                logger.warn("Exception encountered during context initialization - " +
                        "cancelling refresh attempt: " + ex);
            }
            destroyBeans();
            cancelRefresh(ex);
            throw ex;
        }
        finally {
            resetCommonCaches();
        }
    }
}

分析主要的步驟

  1. 首先 prepareRefresh():方法主要是爲容器設置一個狀態(準備工做,記錄下容器的啓動時間、標記「已啓動」狀態、處理配置文件中的佔位符)
  2. 而後接下來是獲取相應的工廠類,AnnotationConfigApplicationContext主要是獲取到DefaultListableBeanFactory,可是若是是XML方式,會在該方法去加載bean定義,咱們不分析這種方式
    • 這步比較關鍵,這步完成後,配置文件/配置類就會解析成一個Bean定義,註冊到 BeanFactory 中,
    • 這裏說的Bean尚未初始化,只是配置信息都提取出來了,
    • 註冊也只是將這些信息都保存到了註冊中心(說到底核心是一個 beanName-> beanDefinition 的 map)
prepareRefresh() 建立容器前的準備工做
protected void prepareRefresh() {
   // 記錄啓動時間,
   // 將 active 屬性設置爲 true,closed 屬性設置爲 false,它們都是 AtomicBoolean 類型
   this.startupDate = System.currentTimeMillis();
   this.closed.set(false);
   this.active.set(true);
   if (logger.isInfoEnabled()) {
      logger.info("Refreshing " + this);
   }
   // Initialize any placeholder property sources in the context environment
   initPropertySources();
   // 校驗 xml 配置文件
   getEnvironment().validateRequiredProperties();
   this.earlyApplicationEvents = new LinkedHashSet<ApplicationEvent>();
}

obtainFreshBeanFactory() 建立 Bean 容器,加載並註冊 Bean IoC初始化裏面最重要的部分。

關鍵是如下幾步:

  • 初始化BeanFactory
  • 加載Bean
  • 註冊Bean

注意:這步完成後,Bean 並無完成初始化,實際的實例並無被建立。

AbstractApplicationContext#obtainFreshBeanFactory()

   protected ConfigurableListableBeanFactory obtainFreshBeanFactory(){
        // 關閉舊的 BeanFactory (若是有),建立新的 BeanFactory,加載 Bean 定義、註冊 Bean 等等
        refreshBeanFactory();
        // 返回上一步剛剛建立的BeanFactory
        ConfigurableListableBeanFactory beanFactory = getBeanFactory();
        if (logger.isDebugEnabled()) {
            logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
        }
        return beanFactory;
    }

AbstractRefreshableApplicationContext#refreshBeanFactory()

protected final void refreshBeanFactory() throws BeansException {
        // 若是 ApplicationContext 已經加載過 BeanFactory,銷燬全部的Bean,關閉BeanFactory
        // 注意點:應用中BeanFactory是能夠有多個的,這裏可不是說全局是否有BeanFactory
        // 而是說當前的ApplicationContext有沒有BeanFactory!
        if (hasBeanFactory()) {
            destroyBeans();
            closeBeanFactory();
        }
        try {
            // 初始化一個 DefaultListableBeanFactory
            DefaultListableBeanFactory beanFactory = createBeanFactory();
            // 用於 BeanFactory 的序列化,通常人應該用不到吧...
            beanFactory.setSerializationId(getId());
            // 下面是兩個重點方法
            // 設置 BeanFactory 的兩個重要屬性
            // 是否容許 Bean 覆蓋、是否容許循環引用
            customizeBeanFactory(beanFactory);
            // 加載BeanDefinition到BeanFactory  單獨拉出來說
            loadBeanDefinitions(beanFactory);
            synchronized (this.beanFactoryMonitor) {
                this.beanFactory = beanFactory;
            }
        }
        catch (IOException ex) {
            throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
        }
   }

能夠感受到一個設計思路,ApplicationContext 繼承自 BeanFactory,可是它不該該被理解爲 BeanFactory 的實現類,而是說其內部持有一個實例化的 BeanFactory(DefaultListableBeanFactory)。之後全部的 BeanFactory 相關的操做實際上是委託給這個實例來處理的。

customizeBeanFactory

    protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
        if (this.allowBeanDefinitionOverriding != null) {
            beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
        }
        if (this.allowCircularReferences != null) {
            beanFactory.setAllowCircularReferences(this.allowCircularReferences);
        }
    }

BeanDefinition 的覆蓋問題可能會有開發者碰到這個坑,就是在配置文件中定義 bean 時使用了相同的 id 或 name。

默認狀況下,allowBeanDefinitionOverriding 屬性爲 null(Boolean類型),若是在同一配置文件中重複了,會拋錯,可是若是不是同一配置文件中,會發生覆蓋。

  • 循環引用也很好理解:A 依賴 B,而 B 依賴 A。或 A 依賴 B,B 依賴 C,而 C 依賴 A。

  • 默認狀況下,Spring 容許循環依賴,固然若是你在 A 的構造方法中依賴 B,在 B 的構造方法中依賴 A 是不行的。

loadBeanDefinitions(beanFactory) 加載BeanDefinition

    /**
     * Load bean definitions into the given bean factory, typically through
     * delegating to one or more bean definition readers.
     * @param beanFactory the bean factory to load bean definitions into
     * @throws BeansException if parsing of the bean definitions failed
     * @throws IOException if loading of bean definition files failed
     * @see org.springframework.beans.factory.support.PropertiesBeanDefinitionReader
     * @see org.springframework.beans.factory.xml.XmlBeanDefinitionReader
     */
    protected abstract void loadBeanDefinitions(DefaultListableBeanFactory beanFactory)
            throws BeansException, IOException;

ClassPathXmlApplicationContext 是按照解析XML的加載方式。看javadoc的描述,是經過XmlBeanDefinitionReader來載入Bean Definitions。

    /**
     * Loads the bean definitions via an XmlBeanDefinitionReader.
     * @see org.springframework.beans.factory.xml.XmlBeanDefinitionReader
     * @see #initBeanDefinitionReader
     * @see #loadBeanDefinitions
     */
    @Override
    protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
        // Create a new XmlBeanDefinitionReader for the given BeanFactory.
        XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
        // Configure the bean definition reader with this context's
        // resource loading environment.
        beanDefinitionReader.setEnvironment(this.getEnvironment());
        beanDefinitionReader.setResourceLoader(this);
        beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
        // Allow a subclass to provide custom initialization of the reader,
        // 初始化Reader 不重要,看下這個方法的javadoc就很好理解了
        initBeanDefinitionReader(beanDefinitionReader);
        // 真正重要的步驟!!
        // 用Reader去加載XML配置
        loadBeanDefinitions(beanDefinitionReader);
    }

loadBeanDefinitions(beanDefinitionReader)

    /**
     * Load the bean definitions with the given XmlBeanDefinitionReader.
     * 看這句註釋:this method is just supposed to load and/or register bean definitions.
     */
    protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
        Resource[] configResources = getConfigResources();
        if (configResources != null) {
            reader.loadBeanDefinitions(configResources);
        }
        String[] configLocations = getConfigLocations();
        if (configLocations != null) {
            // 這個分支,經過路徑名去獲取Resource,會和上面的方法異曲同工
            reader.loadBeanDefinitions(configLocations);
        }
    }

AbstractBeanDefinitionReader#loadBeanDefinitions(Resource... resources)

    @Override
    public int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException {
        Assert.notNull(resources, "Resource array must not be null");
        int counter = 0;
        for (Resource resource : resources) {
            // 遍歷解析XML文件,加載 BeanDefinition
            counter += loadBeanDefinitions(resource);
        }
        return counter;
    }

接下去的源碼不細講,這裏載入分爲兩大步,

  1. 就是經過調用XML的解析器獲取到 document 對象,完成通用XML解析;

  2. 就是按照Spring的Bean規則進行解析。

    • Spring的Bean規則進行解析這個過程是BeanDefinitionDocumentReader來實現的,裏面包含了各類Spring Bean定義規則的處理。

    • 這裏我以爲核心知識點就是Spring Bean規則的解析,簡單點來講,裏面包含了咱們在XML配置的那些信息,怎麼解析成容器中 BeanDefinition的規則和步驟。這部分因爲和主要流程關係不大。

    • 在這由於Spring 的 Bean配置方式有不少,解析配置信息到BeanDefinition的實現方式也有不少,XML又是如今少用的方式,因此關於XML中的Spring Bean規則的解析的詳細源碼就先略過了。

咱們來看下prepareBeanFactory(beanFactory)這個方法

設置 BeanFactory的類加載器,添加幾個 BeanPostProcessor,手動註冊幾個特殊的 bean

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    //設置類加載器,爲當前應用的application的類加載器
    beanFactory.setBeanClassLoader(getClassLoader());
    //爲bean工廠設置一個標準的SPEL表達式解析器
    beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
    //爲bean工廠設置一個資源編輯器,爲了後面bean初始化時,給bean對象賦值
    beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
    //忽略如下接口的bean,這些bean都有set方法,不會對這些bean進行屬性賦值
    beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
    beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
    beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
    beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
    beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
    beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
    beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
    //註冊了工廠實例,若是咱們在程序中注入BeanFactory,就是從這裏註冊的獲取到的
    beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
    beanFactory.registerResolvableDependency(ResourceLoader.class, this);
    beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
    beanFactory.registerResolvableDependency(ApplicationContext.class, this);
    //註冊事件監聽器的bean後置處理接口
    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
    //處理AOP的後置處理器
    if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
        beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
        beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
    }
    //註冊bean工廠的環境屬性
    if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
        beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
    }
    if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
        beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
    }
    if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
        beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
    }
}

接下來分析postProcessBeanFactory(beanFactory);

  • 這裏須要知道BeanFactoryPostProcessor 這個知識點,Bean 若是實現了此接口, 那麼在容器初始化之後,Spring 會負責調用裏面的 postProcessBeanFactory 方法。

    • 提供給子類的擴展點,到這裏的時候,全部的Bean都加載、註冊完成了,可是都尚未初始化。

    • 具體的子類能夠在這步的時候添加一些特殊的 BeanFactoryPostProcessor 的實現類或作點什麼事。

    • 該方法沒有作實際的事情,主要是把ServletContextAwareProcessor後置處理器,給註冊進去。

    • 實現ServletContextAware接口獲取上下文容器,就是從這裏注入的。

protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    if (this.servletContext != null) {
        beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext));
        beanFactory.ignoreDependencyInterface(ServletContextAware.class);
    }
    WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext);
    WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext);
}

接下來分析invokeBeanFactoryPostProcessors(beanFactory);

調用BeanFactoryPostProcessor實現類 postProcessBeanFactory(factory) 方法

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    //獲取FactoryPostProcessors,Spring內置的和本身設置的,而後供接下來的調用
    PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
    if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
        beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
        beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
    }
}

public static void invokeBeanFactoryPostProcessors(
        ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
    //放入已經被處理過的bean
    Set<String> processedBeans = new HashSet<>();
    //當前bean工廠是否實現了BeanDefinitionRegistry,若是有的話,則能夠註冊bean定義
    if (beanFactory instanceof BeanDefinitionRegistry) {
        BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
        List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
        List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
        //循環咱們傳入的bean工廠後置處理器,並加入處處理器集合中
        for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
            if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                BeanDefinitionRegistryPostProcessor registryProcessor =
                        (BeanDefinitionRegistryPostProcessor) postProcessor;
                registryProcessor.postProcessBeanDefinitionRegistry(registry);
                registryProcessors.add(registryProcessor);
            }
            else {
                regularPostProcessors.add(postProcessor);
            }
        }
        //保存當前實例化的BeanDefinitionRegistryPostProcessor
        List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
        //從bean工廠中獲取到繼承了BeanDefinitionRegistryPostProcessor的bean
        String[] postProcessorNames =
              beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
        for (String ppName : postProcessorNames) {
            //實例化優先級最高的BeanDefinitionRegistryPostProcessor
            if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                //實例化出BeanDefinitionRegistryPostProcessor的類,咱們正常初始化這裏只有ConfigurationClassPostProcessor
                currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                processedBeans.add(ppName);
            }
        }
        //對實例化出來的BeanDefinitionRegistryPostProcessor進行排序
        sortPostProcessors(currentRegistryProcessors, beanFactory);
        //把實例化出來的BeanDefinitionRegistryPostProcessor添加進總的集合中供後面調用
        registryProcessors.addAll(currentRegistryProcessors);
        //調用剛實例化出來的bean,註冊bean定義
        invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
        //清空調用後的BeanDefinitionRegistryPostProcessor
        currentRegistryProcessors.clear();

        postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
        for (String ppName : postProcessorNames) {
            //實例化實現了Ordered接口的BeanDefinitionRegistryPostProcessor
            if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
                currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                processedBeans.add(ppName);
            }
        }
        sortPostProcessors(currentRegistryProcessors, beanFactory);
        registryProcessors.addAll(currentRegistryProcessors);
        invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
        currentRegistryProcessors.clear();
        //調用沒有實現任何優先級接口的BeanDefinitionRegistryPostProcessor
        boolean reiterate = true;
        while (reiterate) {
            reiterate = false;
            postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            for (String ppName : postProcessorNames) {
                if (!processedBeans.contains(ppName)) {
                    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    processedBeans.add(ppName);
                    reiterate = true;
                }
            }
            sortPostProcessors(currentRegistryProcessors, beanFactory);
            registryProcessors.addAll(currentRegistryProcessors);
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
            currentRegistryProcessors.clear();
        }
        //調用 BeanDefinitionRegistryPostProcessor.postProcessBeanFactory方法
        invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
        //調用本身實現的BeanDefinitionRegistryPostProcessor.postProcessBeanFactory方法
        invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
    }
    else {
        //沒有實現BeanDefinitionRegistry接口的bean工廠,直接調用invokeBeanFactoryPostProcessors
        invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
    }
    //調用全部的BeanDefinitionRegistryPostProcessor完畢
    //獲取容器中全部的 BeanFactoryPostProcessor
    String[] postProcessorNames =
            beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
    //執行全部BeanFactoryPostProcessor.postProcessBeanFactory方法,按照order接口排序
    List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
    List<String> orderedPostProcessorNames = new ArrayList<>();
    List<String> nonOrderedPostProcessorNames = new ArrayList<>();
    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(priorityOrderedPostProcessors, beanFactory);
    invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

    List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
    for (String postProcessorName : orderedPostProcessorNames) {
        orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
    }
    sortPostProcessors(orderedPostProcessors, beanFactory);
    invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

    List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
    for (String postProcessorName : nonOrderedPostProcessorNames) {
        nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
    }
    invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
    //執行完成全部BeanFactoryPostProcessor.postProcessBeanFactory方法,清除全部緩存信息
    beanFactory.clearMetadataCache();
}
//咱們接下來主要是看ConfigurationClassPostProcessor調用postProcessBeanDefinitionRegistry方法
private static void invokeBeanDefinitionRegistryPostProcessors(
        Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {
    for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
        postProcessor.postProcessBeanDefinitionRegistry(registry);
    }
}

接下來主要針對於,ConfigurationClassParser類進行解析操做處理

public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
    int registryId = System.identityHashCode(registry);
    if (this.registriesPostProcessed.contains(registryId)) {
        throw new IllegalStateException(
                "postProcessBeanDefinitionRegistry already called on this post-processor against " + registry);
    }
    if (this.factoriesPostProcessed.contains(registryId)) {
        throw new IllegalStateException(
                "postProcessBeanFactory already called on this post-processor against " + registry);
    }
    this.registriesPostProcessed.add(registryId);
    processConfigBeanDefinitions(registry);
}

public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
    List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
    String[] candidateNames = registry.getBeanDefinitionNames();
    //循環最開始初始化的全部bean定義
    for (String beanName : candidateNames) {
        BeanDefinition beanDef = registry.getBeanDefinition(beanName);
        //對配置類(帶有@Configuration標籤)進行標記,後續實例化時有用
        if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) != null) {
            if (logger.isDebugEnable()) {
                logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
            }
        }
        //進行標記,添加到配置類,候選集合中
        else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
            configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
        }
    }
    if (configCandidates.isEmpty()) {
        return;
    }
    //對全部配置類進行排序
    configCandidates.sort((bd1, bd2) -> {
        int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
        int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
        return Integer.compare(i1, i2);
    });
    // 建立咱們經過@ComponentScan導入進來的bean name的生成器
    // 建立咱們經過@Import導入進來的bean的名稱
    SingletonBeanRegistry sbr = null;
    if (registry instanceof SingletonBeanRegistry) {
        sbr = (SingletonBeanRegistry) registry;
        if (!this.localBeanNameGeneratorSet) {
            BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(
                    AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR);
            if (generator != null) {
                this.componentScanBeanNameGenerator = generator;
                this.importBeanNameGenerator = generator;
            }
        }
    }
    if (this.environment == null) {
        this.environment = new StandardEnvironment();
    }
    //建立一個類解析器
    ConfigurationClassParser parser = new ConfigurationClassParser(
            this.metadataReaderFactory, this.problemReporter, this.environment,
            this.resourceLoader, this.componentScanBeanNameGenerator, registry);

    Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
    Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
    do {
        /**解析配置類,包括@Component、@ComponentScans等須要掃描的類,都會被解析出來放入bean定義容器
         *@Configuration配置類爲full配置類,其餘的爲lite配置類
         **/
        parser.parse(candidates);
        parser.validate();
        //獲取到解析出來的配置類
        Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
        configClasses.removeAll(alreadyParsed);
        if (this.reader == null) {
            this.reader = new ConfigurationClassBeanDefinitionReader(
                    registry, this.sourceExtractor, this.resourceLoader, this.environment,
                    this.importBeanNameGenerator, parser.getImportRegistry());
        }
        //把全部@Import、@Bean解析出來的bean定義放入容器
        this.reader.loadBeanDefinitions(configClasses);
        alreadyParsed.addAll(configClasses);
        candidates.clear();
        if (registry.getBeanDefinitionCount() > candidateNames.length) {
            String[] newCandidateNames = registry.getBeanDefinitionNames();
            Set<String> oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames));
            Set<String> alreadyParsedClasses = new HashSet<>();
            for (ConfigurationClass configurationClass : alreadyParsed) {
                alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
            }
            for (String candidateName : newCandidateNames) {
                if (!oldCandidateNames.contains(candidateName)) {
                    BeanDefinition bd = registry.getBeanDefinition(candidateName);
                    if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) &&
                            !alreadyParsedClasses.contains(bd.getBeanClassName())) {
                        candidates.add(new BeanDefinitionHolder(bd, candidateName));
                    }
                }
            }
            candidateNames = newCandidateNames;
        }
    }
    while (!candidates.isEmpty());
    if (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
        sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
    }
    if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
        ((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();
    }
}
//咱們再來看看ConfigurationClassPostProcessor.invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    int factoryId = System.identityHashCode(beanFactory);
    if (this.factoriesPostProcessed.contains(factoryId)) {
        throw new IllegalStateException(
                "postProcessBeanFactory already called on this post-processor against " + beanFactory);
    }
    this.factoriesPostProcessed.add(factoryId);
    if (!this.registriesPostProcessed.contains(factoryId)) {
        processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory);
    }
    //這裏會修改@Configuration配置類的bean定義,到時候實例化bean時,會使用CGLIB建立動態代理,@Bean中調用獲取的bean都是容器中的bean,其餘配置類的bean,獲取的都是new出來的
    enhanceConfigurationClasses(beanFactory);
    beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));
}

講了bean定義的加載過程,如今咱們來說一下bean的實例化過程,bean的實例化,主要是finishBeanFactoryInitialization(beanFactory);這個方法

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
    //bean工廠建立轉化器
    if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
            beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
        beanFactory.setConversionService(
                beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
    }
    if (!beanFactory.hasEmbeddedValueResolver()) {
        beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
    }
    //實例化AOP相關的組件
    String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
    for (String weaverAwareName : weaverAwareNames) {
        //調用工廠實例化方法,這個方法咱們後面來分析
        getBean(weaverAwareName);
    }
    beanFactory.setTempClassLoader(null);
    //凍結全部bean定義,在實例化時,不容許再修改bean定義
    beanFactory.freezeConfiguration();
    //實例化全部bean
    beanFactory.preInstantiateSingletons();
}

Spring IOC容器bean的實例化,到這基本就完成了,此次全部源代碼的分析把重要的地方,大體流程都講了一遍,可是有不少細節沒有講到,總體屬於框架整體深刻流程原理介紹。

相關文章
相關標籤/搜索