Spring原码解析之SpringMVC容器如何获取配置文件的bean

上一次,我们在

 Spring原码解析之SpringMVC(DispatcherServlet)初始化流程

中留下了一个方法还没有探究,如图:

这一次我们将会探究一下 configureAndRefreshWebApplicationContext() 这个方法!

FrameworkServlet.java

	protected void configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac) {
		if (ObjectUtils.identityToString(wac).equals(wac.getId())) {
			// The application context id is still set to its original default value
			// -> assign a more useful id based on available information
			if (this.contextId != null) {
				wac.setId(this.contextId);
			}
			else {
				// Generate default id...
				//设置容器的默认id
				wac.setId(ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX +
						ObjectUtils.getDisplayString(getServletContext().getContextPath()) + '/' + getServletName());
			}
		}

		//设置容器的一些初始化配置 不是我们的关乎点
		wac.setServletContext(getServletContext());
		wac.setServletConfig(getServletConfig());
		wac.setNamespace(getNamespace());
        
//这是一个监听器,当发送请求时会调用,只需要实现ApplicationListener接口并注入给容器
		wac.addApplicationListener(new SourceFilteringListener(wac, new ContextRefreshListener()));

		// The wac environment's #initPropertySources will be called in any case when the context
		// is refreshed; do it eagerly here to ensure servlet property sources are in place for
		// use in any post-processing or initialization that occurs below prior to #refresh
		ConfigurableEnvironment env = wac.getEnvironment();
		if (env instanceof ConfigurableWebEnvironment) {
			((ConfigurableWebEnvironment) env).initPropertySources(getServletContext(), getServletConfig());
		}

		//什么也没干 。。。。。。。
		postProcessWebApplicationContext(wac);

		//同样 也没干什么 。。。。。。
		applyInitializers(wac);
		//主要是这个方法  这个方法就在下面
		wac.refresh();
	}
----------------------

	    public void refresh() throws BeansException, IllegalStateException {
        Object var1 = this.startupShutdownMonitor;
        synchronized(this.startupShutdownMonitor) {
            this.prepareRefresh();

            //创建bean工厂 通过obtainFreshBeanFactory获取bean
            ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
            //走完上面那一步已经拿到了文件里的bean了但是只是以读取文件的方式拿到名称
            this.prepareBeanFactory(beanFactory);

            //通过反射等方式 代理的方式真正的创建bean并放入bean工厂中
            //这里先不做深入  我将会在后面研究ioc容器创建时分析
            //可以参考我的IOC容器创建过程的博客
            try {
//后置处理器
                this.postProcessBeanFactory(beanFactory);
//反射调用后置处理器
                this.invokeBeanFactoryPostProcessors(beanFactory);
//注册bean的后置处理器
                this.registerBeanPostProcessors(beanFactory);
//初始化MessageSource
                this.initMessageSource();
//初始化分发器
                this.initApplicationEventMulticaster();
//模板
                this.onRefresh();
//注册ApplicationListener
                this.registerListeners();
//核心逻辑
                this.finishBeanFactoryInitialization(beanFactory);
//完成创建 发布事件
                this.finishRefresh();
            } catch (BeansException var9) {
                if (this.logger.isWarnEnabled()) {
                    this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
                }

                this.destroyBeans();
                this.cancelRefresh(var9);
                throw var9;
            } finally {
                this.resetCommonCaches();
            }

        }
    }

Spring的原码其实很多都是使用一种模式:责任链模式

慕课网有免费课程:https://www.imooc.com/learn/257

然后是关于反射和IO的知识,慕课网也有,分享给大家:https://www.imooc.com/u/321949/courses?sort=publish

不了解JAVA注解的,这里也有课程:https://www.imooc.com/learn/456

想要更了解Spring原码的,最好先了解这些。。。。。。。。。。

猜你喜欢

转载自blog.csdn.net/qq_41750725/article/details/87611948