上篇文章里最后我们提到了spring会获取当前所处环境后调用它的resolveRequiredPlaceholders
方法,也就是解析我们传递路径参数中的占位符,那么它是如何确定当前处于什么环境的呢?
AbstractRefreshableConfigApplicationContext类会调用它的抽象父类AbstractApplicationContext
类中的getEnvironment方法:
1 | /** |
这个方法的注释很清晰,意思就是以可配置的格式返回当前应用程序上下文的环境对象。我们看到这个方法
已经重写了,它的定义其实是在1
2
3
4
5
6
7
8
9
10
11
12
13
14是干嘛的呢?我们看官方文档:
Interface indicating a component that contains and exposes an {@link Environment} reference.
是一个接口,它可以用来表明一个组件包含并暴露Environment的引用。我们看它的定义就知道了:
```Java
public interface EnvironmentCapable {
/**
* Return the {@link Environment} associated with this component.
*/
//返回跟这个组件关联的环境
Environment getEnvironment();
}
All Spring application contexts are EnvironmentCapable, and the interface is used primarily
for performing {@code instanceof} checks in framework methods that accept BeanFactory
instances that may or may not actually be ApplicationContext instances in order to interact
with the environment if indeed it is available.
所有的Spring应用上下文都是带EnvironmentCapable接口的(可装配Environment),而且接口主要用于在框架方法中执行instanceof
检查,
这些方法接受BeanFactory实例,实例可能是ApplicationContext实例,也可能不是,如果是带EnvironmentCapable那么就可以访问Environment了。
As mentioned, {@link org.springframework.context.ApplicationContext ApplicationContext}
extends EnvironmentCapable, and thus exposes a {@link #getEnvironment()} method; however,
{@link org.springframework.context.ConfigurableApplicationContext ConfigurableApplicationContext}
redefines {@link org.springframework.context.ConfigurableApplicationContext#getEnvironment
getEnvironment()} and narrows the signature to return a {@link ConfigurableEnvironment}.
The effect is that an Environment object is ‘read-only’ until it is being accessed from
a ConfigurableApplicationContext, at which point it too may be configured。
总体意思就是ApplicationContext继承了EnvironmentCapable接口,但是ConfigurableApplicationContext重新定义了getEnvironment方法,
而且返回了一个ConfigurableEnvironment,影响就是Environment对象变只读了,除非从ConfigurableApplicationContext访问,
这个时候它就是可配置的了。
我们在文章一开始就看到AbstractApplicationContext类实现了ConfigurableApplicationContext接口,所以我们看到在getEnvironment方法
中我们可以自己配置environment变量了。那么这个createEnvironment内部到底做了些什么呢?
下回再分解!