从小白的角度看Spring核心流程概览(XML版)-初始化容器前的准备工作

##1.0、创建ClassPathXmlApplicationContext类,并将xml文件路径放入构造函数中

ClassPathXmlApplicationContext context =
                new ClassPathXmlApplicationContext("ApplicationContext.xml");

##1.1、首先我们进入构造函数中:

public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
		//此处将我们传过来的配置文件封装成数组,并且调用一个重载方法
		//ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
        this(new String[]{configLocation}, true, (ApplicationContext)null);
    }
	
//分割线
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, @Nullable ApplicationContext parent) throws BeansException {
		//第一步,调用父类的构造方法
        super(parent);
		//第二步:设置我们的配置文件到某个地方
        this.setConfigLocations(configLocations);
		//第三步:判断容器是否需要刷新,如果需要刷新则进入方法
        if(refresh) {
            this.refresh();
        }

    }

##1.1、进入super方法 这里一直往上调了好几层 ClassPathXmlApplicationContext->AbstractXmlApplicationContext->AbstractRefreshableConfigApplicationContext->AbstractRefreshableApplicationContext->AbstractApplicationContext

//在AbstractApplicationContext中才是正真的执行方法
public AbstractApplicationContext(@Nullable ApplicationContext parent) {
	this();
	this.setParent(parent);
}

###1.1.1、this方法

public AbstractApplicationContext() {
	//日志
	this.logger = LogFactory.getLog(this.getClass());
	//设置容器id
	this.id = ObjectUtils.identityToString(this);
	//设置容器名字
	this.displayName = ObjectUtils.identityToString(this);
	//初始化BeanFactoryPostProcessors容器,这个以后会讲。作用是在bean被beanFactory实例化之前做一些操作
	this.beanFactoryPostProcessors = new ArrayList();
	//设置容器是否开始工作
	this.active = new AtomicBoolean();
	//设置容器是否关闭,注意这里都用了线程安全的布尔类型
	this.closed = new AtomicBoolean();
	//没什么用,就是一把锁。我记得以前的版本是直接在字段上new出来的
	this.startupShutdownMonitor = new Object();
	//初始化监听器容器
	this.applicationListeners = new LinkedHashSet();
	//初始化资源解析搜索器,这个有兴趣的可以自己研究(其实就是我不懂....)
	this.resourcePatternResolver = this.getResourcePatternResolver();
}

###1.1.2、SetParent方法

/**
 * 这里使用了经典的责任链模式,如果传入进来的ApplicationContext不为空,则获取它的 
 * Environment(系统资源属性),如果它实现了ConfigurableEnvironment接口,则将其
 * merge进当前的Environment中。
 *
 * 当然我们这里传入的ApplicationContext是null,所有就。。。
 */
	public void setParent(@Nullable ApplicationContext parent) {
        this.parent = parent;
        if(parent != null) {
            Environment parentEnvironment = parent.getEnvironment();
            if(parentEnvironment instanceof ConfigurableEnvironment) {
                this.getEnvironment().merge((ConfigurableEnvironment)parentEnvironment);
            }
        }
    }

##1.2、setConfigLocations方法 实际进入的是AbstractRefreshableConfigApplicationContext的setConfigLocations方法

	/**
	 * 如果配置文件不为空,则将其保存到configLocations属性中
	 */
	public void setConfigLocations(@Nullable String... locations) {
        if(locations != null) {
            Assert.noNullElements(locations, "Config locations must not be null");
            this.configLocations = new String[locations.length];

            for(int i = 0; i < locations.length; ++i) {
				//获取其真正的路径,比如你可能写classpath开头的路径
                this.configLocations[i] = this.resolvePath(locations[i]).trim();
            }
        } else {
            this.configLocations = null;
        }

    }

##1.3 refresh方法 终于进入这个巨头方法了。既然是巨头,那次下次再讲啦~

#笔者自白 欢迎发表意见,以为我写的也不一定是对的,这是笔者拿着这些方法名百度翻译看是什么意思,然后在慢慢看的。(哎,英文垃圾,要好好学学)

转载于:https://my.oschina.net/u/3367603/blog/2207150

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值