1. 程式人生 > >框架源碼系列八:Spring源碼學習之Spring核心工作原理(很重要)

框架源碼系列八:Spring源碼學習之Spring核心工作原理(很重要)

ted pos avi Edito 重要 explicit mon alt 構造函數

目錄:
一、搞清楚ApplicationContext實例化Bean的過程
二、搞清楚這個過程中涉及的核心類
三、搞清楚IOC容器提供的擴展點有哪些,學會擴展
四、學會IOC容器這裏使用的設計模式
五、搞清楚不同創建方式的bean的創建過程

一、ApplicationContext實例化bean的過程

1. 找入口,掃描註冊完beanDefinition後,要創建bean的實例,入口在哪裏?

AnnotationConfigApplicationContext context4 = new AnnotationConfigApplicationContext("com.study.leesmall.spring.service");
    /**
     * Create a new AnnotationConfigApplicationContext, scanning for bean definitions
     * in the given packages and automatically refreshing the context.
     * @param basePackages the packages to check for annotated classes
     */
    public AnnotationConfigApplicationContext(String... basePackages) {
        
this(); scan(basePackages); refresh(); }

org.springframework.context.support.AbstractApplicationContext.refresh()方法就是入口了

    @Override
    public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            
// Prepare this context for refreshing. prepareRefresh(); // Tell the subclass to refresh the internal bean factory. ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // Prepare the bean factory for use in this context. prepareBeanFactory(beanFactory); try { // Allows post-processing of the bean factory in context subclasses. postProcessBeanFactory(beanFactory); // Invoke factory processors registered as beans in the context. invokeBeanFactoryPostProcessors(beanFactory); // Register bean processors that intercept bean creation. registerBeanPostProcessors(beanFactory); // Initialize message source for this context. initMessageSource(); // Initialize event multicaster for this context. initApplicationEventMulticaster(); // Initialize other special beans in specific context subclasses. onRefresh(); // Check for listener beans and register them. registerListeners(); // Instantiate all remaining (non-lazy-init) singletons. finishBeanFactoryInitialization(beanFactory); // 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(); } } }

2. 讀懂org.springframework.context.support.AbstractApplicationContext.refresh()方法的處理流程

技術分享圖片

1)準備context為了刷新

// Prepare this context for refreshing.
            prepareRefresh();

2)從子類獲取BeanFactory實例

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

3)準備BeanFactory為了使用context

            // Prepare the bean factory for use in this context.
            prepareBeanFactory(beanFactory);
/**
     * Configure the factory‘s standard context characteristics,
     * such as the context‘s ClassLoader and post-processors.
     * @param beanFactory the BeanFactory to configure
     */
    protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        // Tell the internal bean factory to use the context‘s class loader etc.
        beanFactory.setBeanClassLoader(getClassLoader());
        beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
        beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

        // Configure the bean factory with context callbacks.
        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 interface not registered as resolvable type in a plain factory.
        // MessageSource registered (and found for autowiring) as a bean.
        beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
        beanFactory.registerResolvableDependency(ResourceLoader.class, this);
        beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
        beanFactory.registerResolvableDependency(ApplicationContext.class, this);

        // Register early post-processor for detecting inner beans as ApplicationListeners.
        beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

        // Detect a LoadTimeWeaver and prepare for weaving, if found.
        if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
            beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
            // Set a temporary ClassLoader for type matching.
            beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
        }

        // Register default environment beans.
        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());
        }
    }

重要1:

beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this)) 這段代碼很重要:

如果你的bean實例裏面需要ApplicationContext,你就需要實現ApplicationContextAwareProcessor這個接口,接口就會把ApplicationContext給到你的bean實例
也可以通過autowired註解去獲取,因為下面的這段代碼:

beanFactory.registerResolvableDependency(ApplicationContext.class, this);

重要2:

註解方式加載配置

package com.study.leesmall.spring.ext;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;

@Configuration
@PropertySource("classpath:/application.properties")
public class MyConfiguration {

    @Bean("messageSource")
    public ReloadableResourceBundleMessageSource getReloadableResourceBundleMessageSource() {
        ReloadableResourceBundleMessageSource rms = new ReloadableResourceBundleMessageSource();
        rms.setBasename("message");
        return rms;
    }
}

重要3:

參數配置的優先級:命令參數 > 環境變量 > properties 文件

        // Register default environment beans.
        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());
        }

命令參數配置方式:進入要運行的類——run as——run configurations——彈出如下界面——選擇——Arguments——添加參數

技術分享圖片

環境變量參數配置方式:進入要運行的類——run as——run configurations——彈出如下界面——選擇——Environment——添加參數

技術分享圖片

properties 文件參數配置方式:直接在Resource目錄下加入properties文件裏面加入參數——在application.xml配置加載properties文件即可

參數:

# jdbc properties
jdbc.driverClassName=xxxx
jdbc.url=xxxx
jdbc.username=xxxx
jdbc.password=xxxx

在application.xml配置加載properties文件

    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations" value="classpath:application.properties"/>
    </bean>

4)對BeanFactory進行預處理

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

說明:這裏用了模板方法設計模式,需要子類去實現的

5)調用執行BeanFactoryPostProcessor (這是一個很重要的擴展點,如果你想在Bean實例化前對BeanFactory進行處理的話,你就可以實現BeanFactoryPostProcessor接口及其子類如BeanDefinitionRegistryPostProcessor,示例如下面的排序優先級代碼)

                // Invoke factory processors registered as beans in the context.
                invokeBeanFactoryPostProcessors(beanFactory);
    /**
     * Instantiate and invoke all registered BeanFactoryPostProcessor beans,
     * respecting explicit order if given.
     * <p>Must be called before singleton instantiation.
     */
    protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
        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()));
        }
    }

委托給PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors())執行

這裏要註意一下Spring裏面有很多類似這樣的委托處理

代碼詳細解讀:

技術分享圖片

技術分享圖片

技術分享圖片

技術分享圖片

技術分享圖片

技術分享圖片

技術分享圖片

說明:

BeanFactoryPostProcessor在實例化bean之前對BeanFactory進行處理的
BeanPostProcessor在bean實例化後,對bean進行處理的
這兩個類用了觀察者模式
AbstractApplicationContextrefresh模板方法模式
執行優先級:priorityOrded>orded

執行順序示例:

優先排序的:

package com.study.leesmall.spring.ext;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.core.PriorityOrdered;
import org.springframework.stereotype.Component;

@Component
public class MyBeanDefinitonRegistryPostProcessor3 implements BeanDefinitionRegistryPostProcessor, PriorityOrdered {

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        System.out.println("--- MyBeanDefinitonRegistryPostProcessor3.postProcessBeanFactory 被執行了。");

    }

    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        System.out.println("--- MyBeanDefinitonRegistryPostProcessor3.postProcessBeanDefinitionRegistry 被執行了。");
    }

    @Override
    public int getOrder() {
        return 1;
    }

}

普通排序的:

package com.study.leesmall.spring.ext;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;

@Component
public class MyBeanDefinitonRegistryPostProcessor2 implements BeanDefinitionRegistryPostProcessor, Ordered {

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        System.out.println("--- MyBeanDefinitonRegistryPostProcessor2.postProcessBeanFactory 被執行了。");

    }

    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        System.out.println("--- MyBeanDefinitonRegistryPostProcessor2.postProcessBeanDefinitionRegistry 被執行了。");
    }

    @Override
    public int getOrder() {
        return 0;
    }

}

沒有排序的:

package com.study.leesmall.spring.ext;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.stereotype.Component;

@Component
public class MyBeanDefinitonRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        System.out.println("--- MyBeanDefinitonRegistryPostProcessor.postProcessBeanFactory 被執行了。");

    }

    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        System.out.println("--- MyBeanDefinitonRegistryPostProcessor.postProcessBeanDefinitionRegistry 被執行了。");
    }

}

運行結果:

--- MyBeanDefinitonRegistryPostProcessor3.postProcessBeanDefinitionRegistry 被執行了。
--- MyBeanDefinitonRegistryPostProcessor2.postProcessBeanDefinitionRegistry 被執行了。
--- MyBeanDefinitonRegistryPostProcessor.postProcessBeanDefinitionRegistry 被執行了。
--- MyBeanDefinitonRegistryPostProcessor3.postProcessBeanFactory 被執行了。
--- MyBeanDefinitonRegistryPostProcessor2.postProcessBeanFactory 被執行了。
--- MyBeanDefinitonRegistryPostProcessor.postProcessBeanFactory 被執行了。

6)向BeanFactory註冊BeanPostProcessor(這是一個很重要的擴展點,如果你想在Bean實例化後對Bean進行處理的話)

registerBeanPostProcessors(beanFactory)

獲得用戶註冊的BeanPostProcessor的bean定義,創建他們的實例,註冊到BeanFactory,對bean實例化後進行處理

7)initMessageSource();初始化國際化資源文件

示例:

package com.study.leesmall.spring.ext;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;

//國際化 給入messageSource的bean實例到bean工廠
@Configuration
@PropertySource("classpath:/application.properties")
public class MyConfiguration {

    @Bean("messageSource")
    public ReloadableResourceBundleMessageSource getReloadableResourceBundleMessageSource() {
        ReloadableResourceBundleMessageSource rms = new ReloadableResourceBundleMessageSource();
        rms.setBasename("message");
        return rms;
    }
}

8)initApplicationEventMulticaster 了解即可
初始化Application Event廣播器,把所有事件廣播出去

9)執行onRefresh(); 由子類來提供實現

10)registerListeners() (這是一個很重要的擴展點,如果你想對容器工作過程中發生的節點事件進行一些處理,比如容器要刷新、容器要關閉了,那麽你就可以實現ApplicationListener)
註冊ApplicationListener:獲得用戶註冊的ApplicationListener的bean定義,創建他們的實例註冊到第8步初始化的廣播器上

技術分享圖片

示例代碼:

package com.study.leesmall.spring.ext;

import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;

//如果你想對容器工作過程中發生的節點事件進行一些處理,比如容器要刷新、容器要關閉了,那麽你就可以實現ApplicationListener
@Component
public class MyApplicationListener implements ApplicationListener<ApplicationEvent> {

    @Override
    public void onApplicationEvent(ApplicationEvent event) {
        System.out.println("-----收到應用事件:" + event);
    }
}

11)finishBeanFactoryInitialization(beanFactory); 完成剩余的單例bean的實例化,為了提前實例化,後面不用getBean去創建實例

a)什麽時候實例化bean?
  單例bean可以在啟動時實例化好,這樣能提高使用時的效率
  原型bean在getBean(beanName)的時候實例化
b)單例bean和原型bean實例化的過程有區別嗎?
  沒有區別的
c)Spring中支持的bean實例創建的方式有幾種?分別如何配置的,如何來獲取Bean實例的?
  創建bean實例的方式:構造函數方式、工廠方式(靜態工廠方式、非靜態工廠方式)、實現FactoryBean的方式

技術分享圖片

工廠方式創建bean實例示例代碼:

package com.study.leesmall.spring.sample.factory;

import com.study.leesmall.spring.service.CombatService;
import com.study.leesmall.spring.service.LoveService;
import com.study.leesmall.spring.service.LoveServiceImpl;

//工廠方式創建bean實例
public class LoveServiceFactory {

    //靜態工廠方式創建bean實例
    public static LoveService getLoveServiceFromStaticFactoryMethod() {
        return new LoveServiceImpl();
    }

    //非靜態工廠方式創建bean實例
    public CombatService getCombatServiceFromMemberFactoryMethod(int time) {
        return new CombatService(time);
    }
}

實現FactoryBean的方式創建bean實例示例代碼:

package com.study.leesmall.spring.sample.factory;

import org.springframework.beans.factory.FactoryBean;

import com.study.leesmall.spring.service.LoveService;
import com.study.leesmall.spring.service.LoveServiceImpl;

//實現FactoryBean的方式創建bean實例
public class LoveServiceFactoryBean implements FactoryBean<LoveService> {

    @Override
    public LoveService getObject() throws Exception {
        return new LoveServiceImpl();
    }

    @Override
    public Class<?> getObjectType() {
        return LoveService.class;
    }

}

那麽上面的創建bean實例的方式怎麽在xm裏面配置呢:

    <!--靜態工廠方式的配置  -->
    <bean id="loveService" class="com.study.leesmall.spring.sample.factory.LoveServiceFactory" 
        factory-method="getLoveServiceFromStaticFactoryMethod">
        <property name="combatService" ref="combatService"></property>
    </bean>
    <!--非靜態工廠方式的配置  -->
    <bean id="loveServiceFactory" class="com.study.leesmall.spring.sample.factory.LoveServiceFactory"> 
    </bean>
        <bean id="combatService" factory-bean="loveServiceFactory" factory-method="getCombatServiceFromMemberFactoryMethod">
        <constructor-arg type="int" value="60" />
    </bean>
    <!--實現FactoryBean的方式的配置  -->
    <bean name="loveService2" class="com.study.leesmall.spring.sample.factory.LoveServiceFactoryBean"></bean>

那麽註解方式又怎麽配置呢:

工廠方式創建bean實例註解配置:

import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

import com.study.leesmall.spring.service.CombatService;
import com.study.leesmall.spring.service.LoveService;
import com.study.leesmall.spring.service.LoveServiceImpl;

//工廠方式創建bean實例
@Component
public class LoveServiceFactory {

    //靜態工廠方式創建bean實例
    @Bean
    public static LoveService getLoveServiceFromStaticFactoryMethod() {
        return new LoveServiceImpl();
    }

    //非靜態工廠方式創建bean實例
    @Bean
    public CombatService getCombatServiceFromMemberFactoryMethod(int time) {
        return new CombatService(time);
    }
}

實現FactoryBean的方式創建bean實例註解配置:

import org.springframework.beans.factory.FactoryBean;
import org.springframework.stereotype.Component;

import com.study.leesmall.spring.service.LoveService;
import com.study.leesmall.spring.service.LoveServiceImpl;

//實現FactoryBean的方式創建bean實例
@Component
public class LoveServiceFactoryBean implements FactoryBean<LoveService> {

    @Override
    public LoveService getObject() throws Exception {
        return new LoveServiceImpl();
    }

    @Override
    public Class<?> getObjectType() {
        return LoveService.class;
    }

}

代碼跟蹤:

入口:org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(ConfigurableListableBeanFactory)

數據類型的轉換:

// Initialize conversion service for this context.
        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));
        }

數據類型的轉換對應在xml配置裏面的寫法:

    <bean id="combatService" class="com.study.leesmall.spring.service.CombatService">
        <constructor-arg type="int" value="60" />
    </bean>

初始化內嵌值的解析器,如properties文件裏面配置的值就需要這種解析器:

    // Register a default embedded value resolver if no bean post-processor
        // (such as a PropertyPlaceholderConfigurer bean) registered any before:
        // at this point, primarily for resolution in annotation attribute values.
        if (!beanFactory.hasEmbeddedValueResolver()) {
            beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
        }

AOP:bean實例初始化後,在進行代理增強,不創建原始bean實例,直接創建代理子類的實例

        // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
        String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
        for (String weaverAwareName : weaverAwareNames) {
            getBean(weaverAwareName);
        }

提前實例化剩余的所有單例bean:

// Instantiate all remaining (non-lazy-init) singletons.
        beanFactory.preInstantiateSingletons();

說明:看子類的實現,過程是找到單例bean的名稱,然後getBean(beanName)拿到單例bean的實例

d)beanfactory中getBean()時的創建實例流程

技術分享圖片

代碼跟蹤:

入口:

org.springframework.beans.factory.support.AbstractBeanFactory.getBean(String)
org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(String, Class<T>, Object[], boolean)

技術分享圖片

技術分享圖片

技術分享圖片

技術分享圖片

技術分享圖片

技術分享圖片

下面來看一下真正創建bean實例的方法

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(String, RootBeanDefinition, Object[]):

技術分享圖片

技術分享圖片

看一下org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(String, RootBeanDefinition, Object[])裏面的org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.resolveBeforeInstantiation(String, RootBeanDefinition)

方法:

技術分享圖片

然後看一下上面調用的org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInstantiation(Class<?>, String)方法:

技術分享圖片

註意:

這裏又是一個擴展點, InstantiationAwareBeanPostProcessor 可以在 Bean 實例創建前、後進行增強處理

如果你想在bean實例創建前後進行處理可以繼承InstantiationAwareBeanPostProcessor的子類InstantiationAwareBeanPostProcessorAdaper,然後覆寫裏面你需要實現的方法,創建前處理就實現創建前處理的方法

對比:
BeanPostProcessor可以在bean實例初始化前和初始化後進行處理

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(String, RootBeanDefinition, Object[])

->

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(String, RootBeanDefinition, Object[])

技術分享圖片

技術分享圖片

技術分享圖片

技術分享圖片

看一下org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(String, RootBeanDefinition, BeanWrapper)方法:

技術分享圖片

技術分享圖片

繼續看一下創建bean實例的代碼塊:

        if (instanceWrapper == null) {
            instanceWrapper = createBeanInstance(beanName, mbd, args);
        }

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(String, RootBeanDefinition, Object[])

技術分享圖片

技術分享圖片

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(String, RootBeanDefinition, Constructor<?>[], Object[])

->

org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(String, RootBeanDefinition, Constructor<?>[], Object[])

技術分享圖片

說明:

explicitArgs:當你調用getBean的時候給定的造參數 spring在getbean的時候是可以自己傳入構造參數的,可以不用bean定義裏面指定或者xml裏面配置的構造參數,示例如下:

getbean(“loveService”, .....)

技術分享圖片

技術分享圖片

拓展:

工廠Bean和Bean工廠的區別:
工廠Bean實現了FactoryBean接口的Bean
Bean工廠BeanFactory IOC容器

12)finishRefresh() 發布事件

二、 搞清楚這個過程中涉及的核心類

技術分享圖片

三、 搞清楚IOC容器提供的擴展點有哪些,學會擴展

1. 擴展點:如第一個大標題

一、ApplicationContext實例化bean的過程

2. 讀懂org.springframework.context.support.AbstractApplicationContext.refresh()方法的處理流程

的5)、6)、10)步均為擴展點

5)調用執行BeanFactoryPostProcessor (這是一個很重要的擴展點,如果你想在Bean實例化前對BeanFactory進行處理的話,你就可以實現BeanFactoryPostProcessor接口及其子類如BeanDefinitionRegistryPostProcessor,示例如下面的排序優先級代碼)

6)向BeanFactory註冊BeanPostProcessor(這是一個很重要的擴展點,如果你想在Bean實例化後對Bean進行處理的話)

10)registerListeners() (這是一個很重要的擴展點,如果你想對容器工作過程中發生的節點事件進行一些處理,比如容器要刷新、容器要關閉了,那麽你就可以實現ApplicationListener)
註冊ApplicationListener:獲得用戶註冊的ApplicationListener的bean定義,創建他們的實例註冊到第8步初始化的廣播器上

技術分享圖片

BeanDefinitionRegistryPostProcessor

BeanFactoryPostProcessor

BeanPostProcessorr

ApplicationListener

11)finishBeanFactoryInitialization(beanFactory); 完成剩余的單例bean的實例化,為了提前實例化,後面不用getBean去創建實例的

然後看一下上面調用的org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInstantiation(Class<?>, String)方法的講解

註意:

這裏又是一個擴展點, InstantiationAwareBeanPostProcessor 可以在 Bean 實例創建前、後進行增強處理

如果你想在bean實例創建前後進行處理可以繼承InstantiationAwareBeanPostProcessor的子類InstantiationAwareBeanPostProcessorAdaper,然後覆寫裏面你需要實現的方法,創建前處理就實現創建前處理的方法

對比:
BeanPostProcessor可以在bean實例初始化前和初始化後進行處理

2. Spring容器啟動時完成了哪幾件核心事情:
1)Bean定義的獲得(解析xml或者掃描註解)
2)環境的初始化 env
3)BeanDefinitionRegistryPostProcessor的自動發現與執行
4)BeanFactoryPostProcessor的自動發現與執行
5)BeanPostProcessorr的自動發現與註冊
6)國際化資源初始化
7)事件廣播器的初始化
8)ApplicationListener的自動發現與註冊
9)實例化單例bean

四、 學會IOC容器這裏使用的設計模式

模板方法設計模式、觀察者模式(主要是這兩個)、策略模式、工廠模式

搞清楚不同創建方式的bean的創建過程

完整代碼獲取地址:https://github.com/leeSmall/FrameSourceCodeStudy/tree/master/spring-source-study

框架源碼系列八:Spring源碼學習之Spring核心工作原理(很重要)