欢迎访问我的GitHub
这里分类和汇总了欣宸的全部原创(含配套源码): https://github.com/zq2599/blog_demos
- 学习spring初始化过程是深入了解spring过程中重要的一步,今天我们就以一个简单的demo为例来学习spring初始化的源码;
- 这个demo的源码可以在github下载,地址和链接信息如下表所示:
名称 | 链接 | 备注 |
---|---|---|
项目主页 | https://github.com/zq2599/blog_demos | 该项目在GitHub上的主页 |
git仓库地址(https) | https://github.com/zq2599/blog_demos.git | 该项目源码的仓库地址,https协议 |
git仓库地址(ssh) | git@github.com:zq2599/blog_demos.git | 该项目源码的仓库地址,ssh协议 |
- 这个git项目中有多个文件夹,本章源码在springcoredemo文件夹中,如下图红框所示:
- demo的关键代码如下:
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
Simple bean = context.getBean(Simple.class);
bean.execute();
context.close();
}
- 接下来我们从ClassPathXmlApplicationContext类的构造方法开始,学习spring初始化过程;
- 构造方法会调用另一个构造方法:
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh) throws BeansException {
this(configLocations, refresh, null);
}
- 如上,parent参数为null,refresh为true;
- 接着看下一个被调用的构造方法:
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
throws BeansException {
super(parent);
setConfigLocations(configLocations);
if (refresh) {
refresh();
}
}
- 如上所示,今天我们的分析重点集中在super、setConfigLocations、refresh这三个方法上,接下来开始逐一深入;
类图
- 看源码之前,先打开类图,后面随时会用到:
- 好了,准备完毕,本章我们分析super(parent)方法;
super(parent)
- ClassPathXmlApplicationContext类中调用的super(parent)实际上是AbstractApplicationContext的构造方法:
public AbstractApplicationContext(ApplicationContext parent) {
this();
setParent(parent);
}
- 先看this():
public AbstractApplicationContext() {
this.resourcePatternResolver = getResourcePatternResolver();
}
上述代码将AbstractApplicationContext的resourcePatternResolver 变量赋值,resourcePatternResolver 的作用是根据路径得到类的Resource对象;
- 展开getResourcePatternResolver方法:
protected ResourcePatternResolver getResourcePatternResolver() {
return new PathMatchingResourcePatternResolver(this);
}
- 有意思的是创建PathMatchingResourcePatternResolver对象的时候,AbstractApplicationContext将自身作为ResourceLoader传递给了PathMatchingResourcePatternResolver;
- 将PathMatchingResourcePatternResolver的构造方法和常用的方法放到一起看看,如下:
public PathMatchingResourcePatternResolver(ResourceLoader resourceLoader) {
Assert.notNull(resourceLoader, "ResourceLoader must not be null");
this.resourceLoader = resourceLoader;
}
public ResourceLoader getResourceLoader() {
return this.resourceLoader;
}
@Override
public Resource getResource(String location) {
return getResourceLoader().getResource(location);
}
- 从上述代码可见,在调用getResource方法的时候,实际上执行的是getResourceLoader().getResource(location),也就是AbstractApplicationContext.getResource();
- Resource的处理类已经确定,回到AbstractApplicationContext构造方法,this()我们已经清楚,再看下面的setParent(parent):
@Override
public void setParent(ApplicationContext parent) {
this.parent = parent;
if (parent != null) {
Environment parentEnvironment = parent.getEnvironment();
if (parentEnvironment instanceof ConfigurableEnvironment) {
getEnvironment().merge((ConfigurableEnvironment) parentEnvironment);
}
}
}
- 由于ClassPathXmlApplicationContext的构造方法中parent参数为null,所以这段代码没必要细看了,记住this.parent为null即可;
- 初始化的第一部分就分析完毕了,这部分的主要工作是为后续Resource处理准备好处理类,我自己在看的时候用了以下思维导图来助记:
- 下一篇《spring4.1.8初始化源码学习三部曲之二:setConfigLocations方法》
欢迎关注阿里云开发者社区博客:程序员欣宸
学习路上,你不孤单,欣宸原创一路相伴...