Spring加载流程

这篇文章咱们大略的理解下Spring加载流程。

根底概念

1.bean

bean:说白了就是把一个个实体对象交由spring去创立和治理

2.beanDefinition

beanDefinition是bean的定义。有点像spring对象的"Class"。

3.BeanFactory,ApplicationContext

BeanFactory是一个根底的容器。ApplicationContext是BeanFactory的一个子接口,性能跟弱小,是高级的容器。

4.BeanFactoryPostProcessor ,BeanDefinitionRegistryPostProcessor

两者都是后置处理器。是Spring很重要的拓展点。这两个扩大点的触发机会,都是在BeanDefinition加载之后,Bean实例化之前。
官网倡议是BeanDefinitionRegistryPostProcessor用来增加BeanDefinition,BeanFactoryPostProcessor用于批改BeanDefinition。BeanDefinitionRegistryPostProcessor优先于BeanFactoryPostProcessor执行。

5.BeanPostProcessor

BeanPostProcessor是bean的后置处理器,也是Spring重要的拓展点。它的触发机会是Bean的初始化。postProcessBeforeInitialization初始化前解决,postProcessAfterInitialization初始化后处理。

6.InitializingBean

InitializingBean 实现了 afterPropertiesSet办法就会在bean初始化时被调用

7.BeanFactory ,FactoryBean

为什么要把这两个放在一起,因为他们长得像,除了像,没有其余半毛钱关系。BeanFactory时根底容器,FactoryBean是一个非凡的bean,是一个工厂bean。也是Spring的一个重要的拓展点,通过这个类的getObject()办法创立一个实列对象。很多插件其实就是用的这个,例如mybatis的Mapper是一个接口,没有具体的实现却能够操作数据库,其实时FactoryBean给它产生了一个代理类。

加载根本流程

public ConfigurableApplicationContext run(String... args) {       StopWatch stopWatch = new StopWatch();    stopWatch.start();    ConfigurableApplicationContext context = null;    Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();    configureHeadlessProperty();    // 第一步:获取并启动监听器    SpringApplicationRunListeners listeners = getRunListeners(args);    listeners.starting();        try {        ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);        // 第二步:依据SpringApplicationRunListeners以及参数来筹备环境        ConfigurableEnvironment environment = prepareEnvironment(listeners,applicationArguments);        configureIgnoreBeanInfo(environment);        // 筹备Banner打印器        Banner printedBanner = printBanner(environment);        // 第三步:创立Spring容器        context = createApplicationContext();        exceptionReporters = getSpringFactoriesInstances(                SpringBootExceptionReporter.class,                new Class[] { ConfigurableApplicationContext.class }, context);        // 第四步:Spring容器前置解决        prepareContext(context, environment, listeners, applicationArguments,printedBanner);        // 第五步:刷新容器        refreshContext(context);     // 第六步:Spring容器后置解决        afterRefresh(context, applicationArguments);      // 第七步:收回完结执行的事件        listeners.started(context);        // 第八步:执行Runners        this.callRunners(context, applicationArguments);        stopWatch.stop();        // 返回容器        return context;    }    catch (Throwable ex) {        handleRunFailure(context, listeners, exceptionReporters, ex);        throw new IllegalStateException(ex);    }}

createApplicationContext()这里创立容器,增加一些特定的后置处理器。其中就包含了咱们前面要说的ConfigurationClassPostProcessor这个后置处理器,也能够说它是spring加载中最重要的后置处理器。
refreshContext(context)这个办法是咱们须要重点关注的,这个办法外面就是将咱们的对象交由spring容器去治理,外围办法。

public void refresh() throws BeansException, IllegalStateException {        synchronized (this.startupShutdownMonitor) {            StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");            // 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);                StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");                /**                 * 激活各种BeanFactory处理器,包含BeanDefinitionRegistryBeanFactoryPostProcessor和一般的BeanFactoryPostProcessor                 * 执行对应的postProcessBeanDefinitionRegistry办法 和  postProcessBeanFactory办法                 */                invokeBeanFactoryPostProcessors(beanFactory);                /**                  * 注册拦挡Bean创立的Bean处理器,即注册BeanPostProcessor,不是BeanFactoryPostProcessor,留神两者的区别                  * 留神,这里仅仅是注册,并不会执行对应的办法,将在bean的实例化时执行对应的办法                  */                registerBeanPostProcessors(beanFactory);                beanPostProcess.end();                //国际化                initMessageSource();                // 初始化事件和监听                initApplicationEventMulticaster();                //拓展点                onRefresh();                //注册事件监听                registerListeners();                //初始化bean                finishBeanFactoryInitialization(beanFactory);                //公布容器初始化实现音讯                finishRefresh();            }            catch (BeansException ex) {                if (logger.isWarnEnabled()) {                    logger.warn("Exception encountered during context initialization - " +                            "cancelling refresh attempt: " + ex);                }                // Destroy already created singletons to avoid dangling resources.                destroyBeans();                // Reset 'active' flag.                cancelRefresh(ex);                // Propagate exception to caller.                throw ex;            }            finally {                // Reset common introspection caches in Spring's core, since we                // might not ever need metadata for singleton beans anymore...                resetCommonCaches();                contextRefresh.end();            }        }

invokeBeanFactoryPostProcessors(beanFactory),这个办法会激活BeanDefinitionRegistryPostProcessor的后置处理器,其中就有就包含
ConfigurationClassPostProcessor这个类,它会将符合条件的bean转化为beanDefinition。
finishBeanFactoryInitialization(beanFactory),这个办法将会依据BeanDefinition去初始化bean,这一步实现后咱们的bean就由spring接管了。