Spring容器的創建刷新過程


Spring容器的創建刷新過程

以AnnotionConfigApplicationContext為例,在new一個AnnotionConfigApplicationContext的時候,其構造函數內就會調用父類的refresh方法

public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
    this();
    register(annotatedClasses);
    refresh();// <-- 調用AbstractApplicationContext的refresh方法
}

所以呢,Spring容器的創建過程主要在這個refresh方法里邊。

public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
        // 1、Prepare this context for refreshing.
        prepareRefresh();

        ///2、Tell the subclass to refresh the internal bean factory.
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

        ///3、Prepare the bean factory for use in this context.
        prepareBeanFactory(beanFactory);

        try {
            //4、 Allows post-processing of the bean factory in context subclasses.
            postProcessBeanFactory(beanFactory);

            //5、 Invoke factory processors registered as beans in the context.
            invokeBeanFactoryPostProcessors(beanFactory);

            //6、 Register bean processors that intercept bean creation.
            registerBeanPostProcessors(beanFactory);

            //7、 Initialize message source for this context.
            initMessageSource();

            //8、 Initialize event multicaster for this context.
            initApplicationEventMulticaster();

            //9、 Initialize other special beans in specific context subclasses.
            onRefresh();

            //10、 Check for listener beans and register them.
            registerListeners();

            //11、 Instantiate all remaining (non-lazy-init) singletons.
            finishBeanFactoryInitialization(beanFactory);

            //12、 Last step: publish corresponding event.
            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 {
            // Reset common introspection caches in Spring's core, since we
            // might not ever need metadata for singleton beans anymore...
            resetCommonCaches();
        }
    }
}

我給源碼的每一步都加了序號(1~12),下面來詳細看看每一步都做了些什么。

1、prepareRefresh() 刷新前准備
  1. 設置一些狀態標記,如啟動時間startupDate,closed/active狀態

  2. initPropertySources() 設置init屬性,此方法交給子類去實現

  3. getEnvironment().validateRequiredProperties()

    如果無Environment,則new StandardEnvironment()

    再調用validateRequiredProperties() 校驗參數

  4. earlyApplicationEvents= new LinkedHashSet ();保存容器中的一些早期的事件

2、obtainFreshBeanFactory() 獲取BeanFactory
  1. refreshBeanFactory() 刷新BeanFactory

    GenericApplicationContext的構造方法中new了一個DefaultListableBeanFactory

    通過this.beanFactory.setSerializationId(getId());設置一個唯一的id

  2. getBeanFactory() 返回剛才GenericApplicationContext創建的BeanFactory對象

3、prepareBeanFactory(beanFactory) BeanFactory的准備工作
  1. 設置BeanFactory的類加載器、表達式解析器【StandardBeanExpressionResolver】、ResourceEditorRegistrar

  2. 添加BeanPostProcessor【ApplicationContextAwareProcessor】

  3. 設置不需要自動裝配的接口

    包括【EnvironmentAware、EmbeddedValueResolverAware、ResourceLoaderAware、ApplicationEventPublisherAware、MessageSourceAware、ApplicationContextAware】

  4. 注冊可以解析的自動裝配的接口

    包括【BeanFactory、ResourceLoader、ApplicationEventPublisher、ApplicationContext】

  5. 添加BeanPostProcessor【ApplicationListenerDetector】

  6. 添加AspectJ【類加載時織入LoadTimeWeaver】

  7. 給BeanFactory中注冊一些能用的組件

    1. environment【ConfigurableEnvironment】

    2. systemProperties【Map<String, Object>】

    3. systemEnvironment【Map<String, Object>】

4、postProcessBeanFactory(beanFactory) BeanFactory后置處理

子類通過重寫這個方法來在BeanFactory創建並預准備完成以后做進一步的設置

到這里,BeanFactory的創建及后置處理工作就結束了

5、invokeBeanFactoryPostProcessors(beanFactory) 執行BeanFactory后置方法

BeanFactoryPostProcessors是BeanFactory的后置處理器,在BeanFactory標准初始化之后、全部bean信息都被加載,但是還沒有被實例化的時候執行。

invokeBeanFactoryPostProcessors方法中,主要處理2種類型的接口:

BeanDefinitionRegistryPostProcessor 和 BeanFactoryPostProcessor

■先執行BeanDefinitionRegistryPostProcessor的方法,過程如下:

  1. 獲取所有實現了BeanDefinitionRegistryPostProcessor接口的class

    beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false)
    
  2. 先執行實現了PriorityOrdered優先級接口的BeanDefinitionRegistryPostProcessor

    postProcessor.postProcessBeanDefinitionRegistry(registry)
    
  3. 同理,再執行實現了Order順序接口的BeanDefinitionRegistryPostProcessor;最后執行其他實現了BeanDefinitionRegistryPostProcessor的

Configuration類中通過@Import(ImportBeanDefinitionRegistrar)引入的類就是在這里被調用registerBeanDefinitions方法的…【processor:ConfigurationClassPostProcessor】

public void registerBeanDefinitions(
    AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry)

■再執行BeanFactoryPostProcessor的方法,過程如下:

  1. 獲取所有實現了BeanFactoryPostProcessor接口的class

    beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false)
    
  2. 先執行實現了PriorityOrdered優先級接口的BeanFactoryPostProcessor

    postProcessor.postProcessBeanFactory(beanFactory)
    
  3. 同理,再執行實現了Order順序接口的BeanFactoryPostProcessor;最后執行其他實現了BeanDefinitionRegistryPostProcessor的

6、registerBeanPostProcessors(beanFactory) 注冊bean的后置處理器
  1. 獲取所有實現了BeanPostProcessor接口的class

    beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
    
  2. 把獲取的類按照 是否實現了 PriorityOrdered、Ordered接口、及其他 分成3類

  3. 按照優先級依次調用

    beanFactory.addBeanPostProcessor(postProcessor);
    
  4. 最后注冊一個ApplicationListenerDetector

    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
    

這個Detector的作用是:

在Bean創建完成后檢查是否是ApplicationListener,如果是則加到context中applicationContext.addApplicationListener((ApplicationListener<?>) bean)

7、initMessageSource() 初始化MessageSource組件

MessageSource組件主要用來實現國際化、消息解析處理。

在initMessageSource中,首先看容器中是否有id為messageSource的,類型是MessageSource的組件。如果沒有則new DelegatingMessageSource() 放進去。

后面在處理國際化時,可以注入MessageSource對象,然后使用如下代碼進行國際化

String getMessage(String code, Object[] args, Locale locale)
8、initApplicationEventMulticaster() 初始化事件多波器

在此方法中,首選從BeanFactory中獲取id為“applicationEventMulticaster”的ApplicationEventMulticaster。如果沒有就new SimpleApplicationEventMulticaster(beanFactory)放進去。[多波器,有的也叫派發器]

9、onRefresh() 留給子類重寫
10、registerListeners() 注冊事件監聽器
  1. 從容器中拿到所有的ApplicationListener

  2. 將每個監聽器添加到事件多波器中

    getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName)
    
  3. 處理前面步驟留下的earlyApplicationEvents,earlyApplicationEvents在步驟1.4中初始化為空的LinkedHashSet

    getApplicationEventMulticaster().multicastEvent(earlyEvent)
    
11、finishBeanFactoryInitialization(beanFactory) 初始化所有剩下的單實例bean

核心邏輯在beanFactory.preInstantiateSingletons()方法中。這里面做的事情主要有:

  1. 循環編譯所有的beanNames,獲取RootBeanDefinition

  2. 如果bean 不是抽象的,是單實例的,是懶加載

  3. 判斷是否 是實現FactoryBean接口的Bean

    如果是,先做一些處理,再調getBean

    如果不是,則直接調用getBean(beanName)

  4. getBean(beanName) –> doGetBean(name, null, null, false)

    1. 先獲取緩存中保存的單實例Bean【singletonObjects.get(beanName)】。如果能獲取到說明這個Bean之前被創建過(所有創建過的單實例Bean都會被緩存在ConcurrentHashMap<String, Object>(256)中)

    2. 如果緩存中獲取不到,則開啟下面的創建流程

    3. 先將bean標記為已創建 markBeanAsCreated(beanName)

    4. 獲取Bean的定義信息RootBeanDefinition

    5. 獲取當前Bean依賴的其他Bean[mbd.getDependsOn()],如果有則調用getBean()把依賴的Bean先創建出來

    6. 開啟單實例Bean的創建流程 createBean(beanName, mbd, args)

      1. 准備重寫的方法

      2. 嘗試返回代理對象

        // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
        Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
        
      3. 執行InstantiationAwareBeanPostProcessor

        先觸發:postProcessBeforeInstantiation();
        如果BeforeInstantiation有返回值,再接着執行postProcessAfterInitialization();

        如果resolveBeforeInstantiation返回的不為null,則bean就創建好了

      4. 前面resolveBeforeInstantiation返回的不為null,則返回該bean;為null接着調Object beanInstance = doCreateBean(beanName, mbdToUse, args);創建Bean【step5】

  5. 創建doCreateBean(beanName, mbdToUse, args)

    1. 創建instanceWrapper = createBeanInstance(beanName, mbd, args)

      利用工廠方法 或 對象的構造器 創建出Bean實例

    2. 調用MergedBeanDefinitionPostProcessor的postProcessMergedBeanDefinition(mbd, beanType, beanName);

    3. 給bean屬性賦值 populateBean(beanName, mbd, instanceWrapper)

      1. 賦值前,拿到所有的InstantiationAwareBeanPostProcessor后置處理器,調用postProcessAfterInstantiation()

      2. 再拿到所有的InstantiationAwareBeanPostProcessor后置處理器,調用postProcessPropertyValues()

      3. 賦值 applyPropertyValues(beanName, mbd, bw, pvs);

        為屬性利用setter方法等進行賦值

  6. 初始化bean,調用initializeBean(beanName, exposedObject, mbd)

    1. 執行xxxAware方法 invokeAwareMethods(beanName, bean),包括【BeanNameAware\BeanClassLoaderAware\BeanFactoryAware】

    2. 執行Bean后置處理器的before方法 applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName) 循環調用 beanProcessor.postProcessBeforeInitialization(result, beanName)

    3. 執行bean的初始化方法 invokeInitMethods(beanName, wrappedBean, mbd);

    4. 執行bean的后置處理器的after方法 applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName) 循環調用 beanProcessor.postProcessAfterInitialization(result, beanName)

      Spring的AOP注解實現原理:

      @EnableAspectJAutoProxy引入了繼承自AbstractAutoProxyCreator的AnnotationAwareAspectJAutoProxyCreator

      在AbstractAutoProxyCreator中實現了postProcessAfterInitialization方法,在方法內調用wrapIfNecessary(bean, beanName, cacheKey)方法創建代理對象返回出去,后續放入容器的就是這個代理對象

    5. 注冊bean的銷毀方法 registerDisposableBeanIfNecessary(beanName, bean, mbd);

  7. 將bean加入到singletonObjects中

  8. 所有bean創建完之后,判斷bean是否是SmartInitializingSingleton的實例。如果是,就執行afterSingletonsInstantiated()

12、finishRefresh() 容器創建完成
  1. initLifecycleProcessor() 初始化和生命周期有關的后置處理器

    默認從容器中找是否有lifecycleProcessor的組件【LifecycleProcessor】;如果沒有new DefaultLifecycleProcessor();加入到容器;

  2. 執行onfresh方法

    getLifecycleProcessor().onRefresh()
    
  3. 發布容器刷新完成事件

    publishEvent(new ContextRefreshedEvent(this))
    
  4. 調用LiveBeansView.registerApplicationContext(this)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM