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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132

package org.springframework.boot.context.config;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.BeanUtils;
import org.springframework.context.ApplicationContextException;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.GenericTypeResolver;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;

/**
* {@link ApplicationContextInitializer} that delegates to other initializers that are
* specified under a {@literal context.initializer.classes} environment property.
*
在配置文件中配置的 context.initializer.classes ,由这个类来 instantiate 它们,并 foreach run initialize(xx)
ApplicationContextInitializer 在 context refresh 之前执行,并需要(最好) @Order 或 Ordered

* @author Dave Syer
* @author Phillip Webb
* @since 1.0.0
*/
public class DelegatingApplicationContextInitializer
implements ApplicationContextInitializer<ConfigurableApplicationContext>, Ordered {

// NOTE: Similar to org.springframework.web.context.ContextLoader

private static final String PROPERTY_NAME = "context.initializer.classes";

private int order = 0; // 优先级中等吧

@Override
public void initialize(ConfigurableApplicationContext context) {
ConfigurableEnvironment environment = context.getEnvironment();
List<Class<?>> initializerClasses = getInitializerClasses(environment);
if (!initializerClasses.isEmpty()) {
applyInitializerClasses(context, initializerClasses);
}
}

private List<Class<?>> getInitializerClasses(ConfigurableEnvironment env) {
/**
从配置中读 context.initializer.classes
*/
String classNames = env.getProperty(PROPERTY_NAME);
List<Class<?>> classes = new ArrayList<>();
if (StringUtils.hasLength(classNames)) {
for (String className : StringUtils.tokenizeToStringArray(classNames, ",")) {
classes.add(getInitializerClass(className));
}
}
return classes;
}

private Class<?> getInitializerClass(String className) throws LinkageError {
/**
加载 initializer class
*/
try {
Class<?> initializerClass = ClassUtils.forName(className, ClassUtils.getDefaultClassLoader());
Assert.isAssignable(ApplicationContextInitializer.class, initializerClass);
return initializerClass;
}
catch (ClassNotFoundException ex) {
throw new ApplicationContextException("Failed to load context initializer class [" + className + "]", ex);
}
}

private void applyInitializerClasses(ConfigurableApplicationContext context, List<Class<?>> initializerClasses) {
/**

*/
Class<?> contextClass = context.getClass();
List<ApplicationContextInitializer<?>> initializers = new ArrayList<>();
for (Class<?> initializerClass : initializerClasses) {
initializers.add(instantiateInitializer(contextClass, initializerClass));
}
applyInitializers(context, initializers);
}

private ApplicationContextInitializer<?> instantiateInitializer(Class<?> contextClass, Class<?> initializerClass) {
/**
instantiate initializer
*/
Class<?> requireContextClass = GenericTypeResolver.resolveTypeArgument(initializerClass,
ApplicationContextInitializer.class);
/**
拿到 interface ApplicationContextInitializer<C extends ConfigurableApplicationContext> 泛型 C 的具体类
*/
Assert.isAssignable(requireContextClass, contextClass,
() -> String.format(
"Could not add context initializer [%s] as its generic parameter [%s] is not assignable "
+ "from the type of application context used by this context loader [%s]: ",
initializerClass.getName(), requireContextClass.getName(), contextClass.getName()));
/**
不难理解,这个类本身就是 ConfigurableApplicationContext,所以它读取的 initializers 都得是同一类型
*/
return (ApplicationContextInitializer<?>) BeanUtils.instantiateClass(initializerClass);
}

@SuppressWarnings({ "unchecked", "rawtypes" })
private void applyInitializers(ConfigurableApplicationContext context,
List<ApplicationContextInitializer<?>> initializers) {
// 终级奥义
initializers.sort(new AnnotationAwareOrderComparator());
// @Order / Ordered 排序
for (ApplicationContextInitializer initializer : initializers) {
initializer.initialize(context);
}
/**
如这个类注释所讲,它本身不做初始化,都是代理给了其它 initializers
*/
}

public void setOrder(int order) {
this.order = order;
}

@Override
public int getOrder() {
return this.order;
}

}