ApplicationContext之prepareRefresh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
/**
* Prepare this context for refreshing, setting its startup date and
* active flag as well as performing any initialization of property sources.
*/
protected void prepareRefresh() {
//开始时间
this.startupDate = System.currentTimeMillis();
this.closed.set(false);
this.active.set(true);

if (logger.isInfoEnabled()) {
logger.info("Refreshing " + this);
}

// Initialize any placeholder property sources in the context environment.
//初始化一些属性,默认里面的实现是空的,留给子类使用,扩展点之一
initPropertySources();

// Validate that all properties marked as required are resolvable:
// see ConfigurablePropertyResolver#setRequiredProperties
//得到环境信息,默认的是StandardEnvironment。然后来验证一些必要的属性是否存在,如果不存在,那么此处就会
//抛出异常
//StandardEnvironment用的是委托模式,validateRequiredProperties的时候委托给了自己内部的属性解析器,也就是
//propertyResolver。
//propertyResolver在实例化的时候,会接收属性源,解析器的父类有一个私有集合对象用于储存key;
//validate的时候,会通过解析器的getProperty取值然后验证是否存在;
getEnvironment().validateRequiredProperties();

// Store pre-refresh ApplicationListeners...
//添加一些监听器
if (this.earlyApplicationListeners == null) {
this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
}
else {
// Reset local application listeners to pre-refresh state.
this.applicationListeners.clear();
this.applicationListeners.addAll(this.earlyApplicationListeners);
}

// Allow for the collection of early ApplicationEvents,
// to be published once the multicaster is available...
this.earlyApplicationEvents = new LinkedHashSet<>();
}

下面是一个使用示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package com.vayne.boot;

import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.env.SystemEnvironmentPropertySource;

import java.util.HashMap;
import java.util.Map;

/**
* @author Volcanno
*/
public class Boot {

public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:application.xml");
Map<String, Object> map = new HashMap<>();
map.put("vay", "vayne");
map.put("alis", "alison");
SystemEnvironmentPropertySource seps = new SystemEnvironmentPropertySource("env", map);
context.getEnvironment().getPropertySources().addFirst(seps);
//这里会把vay和alis添加到AbstractPropertyResolver的一个list里面。然后validate的时候,会调用子类的getProperty
context.getEnvironment().setRequiredProperties("vay");
context.getEnvironment().setRequiredProperties("alis");
context.refresh();
Object object = context.getEnvironment().getProperty("alis");
String string = String.valueOf(object);
System.out.println("hello, " + string);
}
}

总结:

可以将一些需要使用的必要的属性设置到contextenvironment里面,然后使用的时候直接取用就可以了。