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


目錄:
一、搞清楚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


免責聲明!

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



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