spring3--SSM和springboot的容器启动

容器启动核心都是通过监听或某个方法来调用ApplicationContext.refresh()。

一、SSM

1、在 web.xml 配置监听器

<!-- spring监听器 -->
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

2、容器启动时会调用 ContextLoaderListener 中的 contextInitialized 方法。

public class ContextLoaderListener extends ContextLoader implements ServletContextListener {

    @Override
    public void contextInitialized(ServletContextEvent event) {
    	initWebApplicationContext(event.getServletContext());
    }

}

3、调用父类的 initWebApplicationContext 方法,在该方法中创建、启动上下文。

public class ContextLoader {
    public WebApplicationContext initWebApplicationContext(ServletContext servletContext) {
    	try {
    		if (this.context == null) {
    		    // 通过 createWebApplicationContext 方法创建上下文,默认创建 XmlWebApplicationContext
    			this.context = createWebApplicationContext(servletContext);
    		}
    		if (this.context instanceof ConfigurableWebApplicationContext) {
    			ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext) this.context;
    			if (!cwac.isActive()) {
    				// 在该方法中调用上下文的 refresh 方法,refresh 就是启动上下文的入口
    				configureAndRefreshWebApplicationContext(cwac, servletContext);
    			}
    		}
    	}
    }
    
    protected void configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac, ServletContext sc) {

    	wac.refresh();
    }
}

二、springboot

1、从启动类开始

2、找到 SpringApplication 中,最后重载的 run 方法

public ConfigurableApplicationContext run(String... args) {    
    ...    
    ConfigurableApplicationContext context = null;   
    ...    
    try {
        ...
        // 通过 createApplicationContext 方法创建上下文,根据 Web 环境不同创建的上下文也不同
        context = createApplicationContext();    
        ...
        // 该方法用于启动上下文
        refreshContext(context);
        ...
    }
    catch (Throwable ex) {
        ...
    } 
    context = createApplicationContext();
}

3、进入 refreshContext 方法,里面调用了 refresh 方法

4、这里最终也是调用 ApplicationContext 的 refresh 方法来启动上下文

三、rerfrsh()方法详解

注意注册postProcess和调用postProcess是不一样的概念!

AbstractApplicationContext
public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
        // 1. 初始化 refresh 的上下文环境,就是记录下容器的启动时间、标记已启动状态、处理配置文件中的占位符
        prepareRefresh();
        // 2. 初始化 BeanFactory,加载并解析配置(xxApplicationContext.loadBeanDefinitions--xxBeanDefinitionReader.load)
        ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
        /* ---至此,已经完成了简单容器的所有功能,下面开始对简单容器进行增强--- */
        // 3. 对 BeanFactory 进行功能增强,如设置BeanFactory的类加载器,添加几个BeanPostProcessor,手动注册几个特殊的 bean
        prepareBeanFactory(beanFactory);

        try {
            // 4. 后置处理 beanFactory,交由子类实现。注册BeanFactoryPostProcessor等
            postProcessBeanFactory(beanFactory);

            // 5. 调用已注册的 BeanFactoryPostProcessor
            invokeBeanFactoryPostProcessors(beanFactory);

            // 6. 注册 BeanPostProcessor,仅仅是注册,调用在getBean的时候
            registerBeanPostProcessors(beanFactory);
            
            // 7. 初始化MessageSource组件(做国际化功能;消息绑定,消息解析)
            initMessageSource();
            // 8. 初始化事件广播器
            initApplicationEventMulticaster();
            // 9. 留给子类实现的模板方法
            onRefresh();
            // 10. 注册事件监听器
            registerListeners();
            
            // 11. 实例化所有非延迟加载的单例(里面会调用已注册的BeanPostProcessor)
            finishBeanFactoryInitialization(beanFactory);

            // 12. 完成刷新过程,发布应用事件
            finishRefresh();
            
        } catch (BeansException ex) {         
            // 13.销毁已经初始化的 singleton 的 Beans,以免有些 bean 会一直占用资源
            this.destroyBeans();          
            // Reset 'active' flag.
            this.cancelRefresh(ex);
            // Propagate exception to caller.
            throw ex;
        } finally {        
            this.resetCommonCaches();
        }
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值