##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方法 终于进入这个巨头方法了。既然是巨头,那次下次再讲啦~
#笔者自白 欢迎发表意见,以为我写的也不一定是对的,这是笔者拿着这些方法名百度翻译看是什么意思,然后在慢慢看的。(哎,英文垃圾,要好好学学)