Back to Javatutorial

SpringBoot启动流程(四):启动IOC容器

docs/Spring全家桶/SpringBoot源码解析/SpringBoot启动流程(四):启动IOC容器.md

1.0.010.9 KB
Original Source

һƪܽ springboot £

ģǼIJ衣

3.10 ˢ ioc

SpringApplication#refreshContext

private void refreshContext(ConfigurableApplicationContext context) {
    // spring
    refresh(context);
    if (this.registerShutdownHook) {
        try {
            // ע ShutdownHook
            context.registerShutdownHook();
        }
        catch (AccessControlException ex) {
            // Not allowed in some environments.
        }
    }
}

  1. refresh(context) spring Ҳǵ AbstractApplicationContext#refresh
  2. context.registerShutdownHook()ע ShutdownHook jvm ̹رʱһЩضIJ

3.10.1 spring

SpringApplication#refresh

protected void refresh(ApplicationContext applicationContext) {
    Assert.isInstanceOf(AbstractApplicationContext.class, applicationContext);
    // spring 
    ((AbstractApplicationContext) applicationContext).refresh();
}

ܼ򵥣ж applicationContext ǷΪ AbstractApplicationContextȻٵ AbstractApplicationContext#refresh()

AbstractApplicationContext#refresh()ǿǴ÷ spring ̡ڱIJǷ spring £ͲչˣҪ˽̵СԲο£

AbstractApplicationContext#refresh() Уspring ṩ˼չ㣺

ǵǰʹõ applicationContext Ϊ AnnotationConfigServletWebServerApplicationContextҲʹЩչ㣬ҪעЩչӦá

1. ǰ׼prepareRefresh()

Է֣initPropertySources() е£

AbstractApplicationContext#refresh
 |- AnnotationConfigServletWebServerApplicationContext#prepareRefresh
  |- AbstractApplicationContext#prepareRefresh
   |- GenericWebApplicationContext#initPropertySources

յõ GenericWebApplicationContext#initPropertySources

protected void initPropertySources() {
    ConfigurableEnvironment env = getEnvironment();
    if (env instanceof ConfigurableWebEnvironment) {
        ((ConfigurableWebEnvironment) env).initPropertySources(this.servletContext, null);
    }
}

Ȼȡ EnvironmentȻжǷΪ ConfigurableWebEnvironment ʵǰ׼ʱʱǵõ Environment Ϊ StandardServletEnvironment ConfigurableWebEnvironment ķϣȻ ConfigurableWebEnvironment#initPropertySources StandardServletEnvironment#initPropertySources

public void initPropertySources(@Nullable ServletContext servletContext, 
        @Nullable ServletConfigservletConfig) {
    // 滻õ servletContextInitParams Ϊ servletContext
    // 滻õ servletConfigInitParams Ϊ servletConfig
    WebApplicationContextUtils.initServletPropertySources(getPropertySources(), 
        servletContext, servletConfig);
}

Ǻܼ򵥣ֻǽ servletContext servletConfig õ Environment С

2. ȡ beanFactory: obtainFreshBeanFactory()

ǰ applicationContext Ը÷չ

3. ׼ beanFactory: prepareBeanFactory(beanFactory)

ǰ applicationContext Ը÷չ

4. չ㣺postProcessBeanFactory(beanFactory)

AnnotationConfigServletWebServerApplicationContext д

@Override
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    // øķ
    super.postProcessBeanFactory(beanFactory);
    // аɨ裬İ
    if (this.basePackages != null && this.basePackages.length > 0) {
        this.scanner.scan(this.basePackages);
    }
    // עbeanΪ
    if (!this.annotatedClasses.isEmpty()) {
        this.reader.register(ClassUtils.toClassArray(this.annotatedClasses));
    }
}

ִй£

  1. ˸ķ super.postProcessBeanFactory(beanFactory)
  2. аɨ裬ͨԷ֣ basePackages Ϊ nul
  3. ע annotatedClasses annotatedClasses Ϊ

Ҫ super.postProcessBeanFactory(beanFactory)÷ ServletWebServerApplicationContext У

@Override
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    // һ BeanPostProcessor
    beanFactory.addBeanPostProcessor(
            new WebApplicationContextServletContextAwareProcessor(this));
    //  ServletContextAware Զע
    beanFactory.ignoreDependencyInterface(ServletContextAware.class);
    // ע web bean ķΧעrequestsessionglobalSession
    registerWebApplicationScopes();
}

ݱȽϼ򵥣Ҫע BeanPostProcessor Լע web bean ÷ΧҪ WebApplicationContextServletContextAwareProcessor ã£

public class WebApplicationContextServletContextAwareProcessor 
        extends ServletContextAwareProcessor {

    private final ConfigurableWebApplicationContext webApplicationContext;

    public WebApplicationContextServletContextAwareProcessor(
            ConfigurableWebApplicationContext webApplicationContext) {
        Assert.notNull(webApplicationContext, "WebApplicationContext must not be null");
        this.webApplicationContext = webApplicationContext;
    }

    /**
     * ȡ ServletContext
     */
    @Override
    protected ServletContext getServletContext() {
        ServletContext servletContext = this.webApplicationContext.getServletContext();
        return (servletContext != null) ? servletContext : super.getServletContext();
    }

    /**
     * ȡ ServletConfig
     */
    @Override
    protected ServletConfig getServletConfig() {
        ServletConfig servletConfig = this.webApplicationContext.getServletConfig();
        return (servletConfig != null) ? servletConfig : super.getServletConfig();
    }

}

ƺûʲôٸ࣬Ǹ BeanPostProcessorҪע postProcessBeforeInitialization() postProcessAfterInitialization()

public class ServletContextAwareProcessor implements BeanPostProcessor {

    ...

    public Object postProcessBeforeInitialization(Object bean, 
            String beanName) throws BeansException {
        //  ServletContext
        if (getServletContext() != null && bean instanceof ServletContextAware) {
            ((ServletContextAware) bean).setServletContext(getServletContext());
        }
        //  ServletConfig
        if (getServletConfig() != null && bean instanceof ServletConfigAware) {
            ((ServletConfigAware) bean).setServletConfig(getServletConfig());
        }
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) {
        return bean;
    }

}

Կ BeanPostProcessor ServletContextAware ServletConfigAware Aware ӿڵģ·ͬ ApplicationAware``BeanFactoryAware һ

5. ִ BeanFactoryPostProcessors: invokeBeanFactoryPostProcessors(beanFactory)

ǰ applicationContext Ը÷չ

ֵһǣУиص BeanFactoryPostProcessor ᱻִУConfigurationClassPostProcessorspringboot Զװע @EnableAutoConfiguration ﴦԶװļءעҲ ConfigurationClassPostProcessor С

6. ע BeanPostProcessor: registerBeanPostProcessors(beanFactory)

ǰ applicationContext Ը÷չ

7. ʼ MessageSource(ڹʻ): initMessageSource()

ǰ applicationContext Ը÷չ

8. ʼ¼㲥initApplicationEventMulticaster()

ǰ applicationContext Ը÷չ

9. չ㣺onRefresh()

ǰ applicationContext Ը÷չΪ ServletWebServerApplicationContext#onRefresh £

@Override
protected void onRefresh() {
    // ø෽
    super.onRefresh();
    try {
        // webtomcat,jetty
        createWebServer();
    }
    catch (Throwable ex) {
        throw new ApplicationContextException(...);
    }
}

web дġ web Ĵ򵥣ҪжϣǺϸ˵

10. ע¼registerListeners()

ǰ applicationContext Ը÷չ

11. ʼ bean: finishBeanFactoryInitialization(beanFactory)

ǰ applicationContext Ը÷չ

12. : finishRefresh()

ǰ applicationContext Ը÷չΪ ServletWebServerApplicationContext#finishRefresh £

@Override
protected void finishRefresh() {
    super.finishRefresh();
    // web
    WebServer webServer = startWebServer();
    if (webServer != null) {
        //  ServletWebServerInitializedEvent ¼
        publishEvent(new ServletWebServerInitializedEvent(webServer, this));
    }
}

/**
 * web
 */
private WebServer startWebServer() {
    WebServer webServer = this.webServer;
    if (webServer != null) {
        webServer.start();
    }
    return webServer;
}

Կ web

13. : resetCommonCaches()

ǰ applicationContext Ը÷չ

3.10.2 ע ShutdownHook

context.registerShutdownHook()÷ AbstractApplicationContext#registerShutdownHook

public abstract class AbstractApplicationContext extends DefaultResourceLoader
        implements ConfigurableApplicationContext {
    ...
    @Override
    public void registerShutdownHook() {
        if (this.shutdownHook == null) {
            // ̵ָ߳
            this.shutdownHook = new Thread(SHUTDOWN_HOOK_THREAD_NAME) {
                @Override
                public void run() {
                    synchronized (startupShutdownMonitor) {
                        //  ShutdownHook 
                        doClose();
                    }
                }
            };
            Runtime.getRuntime().addShutdownHook(this.shutdownHook);
        }
    }

    /**
     * Ĺرղ
     */
    protected void doClose() {
        // Check whether an actual close attempt is necessary...
        if (this.active.get() && this.closed.compareAndSet(false, true)) {
            LiveBeansView.unregisterApplicationContext(this);

            try {
                // ر¼
                publishEvent(new ContextClosedEvent(this));
            }
            catch (Throwable ex) {
                logger.warn(...);
            }

            //  lifecycle  onClose() 
            if (this.lifecycleProcessor != null) {
                try {
                    this.lifecycleProcessor.onClose();
                }
                catch (Throwable ex) {
                    logger.warn(...);
                }
            }

            //  bean
            destroyBeans();

            // ر
            closeBeanFactory();

            // չ㣬ʵ
            onClose();

            // 
            if (this.earlyApplicationListeners != null) {
                this.applicationListeners.clear();
                this.applicationListeners.addAll(this.earlyApplicationListeners);
            }

            //  active ʶ
            this.active.set(false);
        }
    }

    ...

}

Կcontext.registerShutdownHook() ʵ doClose() Ĺرղر spring ĹرգעѾ൱ˣͲˡ

ˣͷˣ spring չ onRefresh() finishRefresh()ǰߴ webServer webServer


ԭӣhttps://my.oschina.net/funcy/blog/4888129 ߸ˮƽд֮ӭָԭףҵתϵ߻Ȩҵתע