深入了解Spring源码细节(1) -getEnvironment是怎么获取到值的?

702 阅读2分钟

01 导引

大家好,今天我们继续接着上一篇《搞清spring源码的脉络,你就知道从哪里开始下手了》继续深挖spring源码。

好了废话不多说,直接进入主题。

02 从一个测试类开始

image.png

image.png

我们从这个测试类debug进入我们今天非常重要的一个类ClassPathXmlApplicationContext的构造器:

image.png

这个构造器里面super(parent)这段代码我们就不看了,主要就是一些调用父类的构造方法,对一些对象进行创建操作【这些我都在源码上标了注释了,如果有需要的可以私信我要github或者码云地址】。

我们来看看setConfigLocations(configLocations)这段代码,这段代码debug进入如下:

image.png

通过注释我们就可以大致看出来setConfigLocations这个方法主要是设置应用程序的上下文的配置路径.这个方法里面有几个地方需要注意的,我们直接进入resolvPath(locations[i]).trim()这个方法;

image.png

这个方法有两个作用的地方,一个是getEnvironment()用于返回一个环境配置(没想好有其他更好的表达比环境配置更好说明)。

另外一个是
resolveRequiredPlaceholders(path)看名称我们就知道他是处理占位符的(例如:${...})。所以在我们看spring源码时有些方法我们大可以见名知意。

我们主要讲一下getEnvironment()这个方法,因为这个方法干的事在后面会用到,所以大家要记住这个方法。

这个方法debug进去如下:

image.png

因为刚进来所以这个environment肯定是没有值的,我们进入了if里面,点开createEnviroment()方法如下:

image.png

这个地方有一个比较有意思的地方就是这个地方的内容是在父类构造器初始化的,但是实际执行其实是调用了子类的方法。这句话看着比较拗口,我们点进去StandardEnvironment()这个方法你就清楚了,debug进去如下图:

image.png

点进去之后你会发现这个类没有做啥操作,这个地方涉及到了java的一个基本功:子类在初始化时首先会隐式的调用父类的无参构造器。

所以我们得去这个类的父类(AbstractEnvironment)的无参构造方法看看:

image.png

image.png

这个customizePropertySources的实现正好在我们一开始进来的子类(StandardEnvironment)中进行了实现:

image.png

这是不是感觉很绕,有点被套娃的感觉,这也是spring让人头疼的地方,针对上面的这个逻辑我画了一下思维导图如下:

image.png

好了今天就分享到这里,下一章我们继续接着往下撸,下一章我们会撸

refresh()这个方法,这个方法是重点中的重点,大家一定要把搞明白。

关注我,一起读书,一起提升认知!