spring-IOC容器源码分析(二)BeanDefinition注册流程

本篇文章主要介绍以下几个部分:

  1. BeanFactory接口体系
  2. BeanDefinition的接口实现类体系
  3. 梳理注册注解配置类流程
  4. 从解析@Scope的流程入手,分析一个通用的spring解析注解属性的流程
  5. java code config基于注解配置的原理

BeanFactory接口体系

以DefaultListableBeanFactory为例梳理一下BeanFactory接口体系的细节

主要接口、抽象类的作用如下:

  1. BeanFactory(根据注册的bean定义来生产bean的功能)
  2. BeanRegistry(bean定义的注册功能)
  3. BeanDefinition(bean的定义信息)

    BeanFactory

  4. BeanFactory:用于访问Spring bean容器的根接口,提供多个重载的getBean方法来获取注册到容器中的bean的实例
  5. HierarchicalBeanFactory:为Spring bean 容器提供父子容器的上下层级关系的能力
  6. ListableBeanFactory:提供遍历Spring bean容器中bean的能力但其方法只检查容器内部bean的定义,而不会真正的实例化bean;并且不会包含其父容器中的bean定义
  7. ConfigurableBeanFactory:提供遍历Spring bean容器的能力,比如向container中增加BeanPostProcessor
  8. AutowireCapableBeanFactory:提供自动注入bean属性的能力,以及其他框架的集成代码可以利用这个接口来连接和填充Spring无法控制的现有bean实例生命周期

BeanRegistry

  1. AliasRegistry:用于管理bean别名的接口
  2. BeanDefinitionRegistry:提供注册BeanDefinition的能力

BeanDefinition

  1. AnnotatedBeanDefinition:注解的元数据
  2. RootBeanDefinition:在Spring bean容器运行期间,通过合并注册到容器中的bean定义生成的bean元数据

总结

在spring的容器接口体系中,我们可以使用原材料、工厂、生产线操作工人、最终产品的关系来类比BeanDefinition、BeanFactory、BeanRegistry、bean实例。
BeanRegistry提供能力将BeanDefinition注册到BeanFactory中,BeanFactory通过其内部的生产线来生成bean实例

BeanDefinition的接口实现类体系

以AnnotatedGenericBeanDefinition为例梳理一下BeanDefinition接口实现类体系

Metadata元数据部分

Metadata元数据部分在其内部包装了需要注册到BeanFactory的类的信息

类图

类关系说明

  1. ClassMetadata,抽象出类的元数据的接口。提供获取类名、判断是否为接口类、是否为注解类、是否为抽象类等功能;
  2. AnnotatedTypeMetadata,定义了接口,用于访问AnnotationMetadata、MethodMetadata这两个类的注解。提供判断是否被指定注解标记、获取指定注解的属性等功能;
  3. AnnotationMetadata,定义了接口,用于访问指定类的注解;如getMetaAnnotationTypes(String annotationName)用于获取指定注解annotationName的元注解集合
  4. StandardClassMetadata,用标准的反射功能实现了ClassMetadata类
  5. StandardAnnotationMetadata,扩展StandardClassMetadata类并实现AnnotationMetadata接口

BeanDefinition部分

BeanDefinition作为注册到BeanFactory中的载体,在具体的实现类中,持有metadata实例。

类图

类关系说明

  1. AttributeAccessor,定义设置和获取属性元数据的接口;
  2. AttributeAccessorSupport,在内部通过LinkedHashMap实现了AttributeAccessor接口;
  3. BeanMetadataElement,持有一个source,具体用途待考究;
  4. BeanMetadataAttribute,实现BeanMetadataElement接口,在其内部以key-value的形式持有bean definition的属性;
  5. BeanMetadataAttributeAccessor,实现BeanMetadataElement接口,并重写部分AttributeAccessorSupport的接口,用于设置和获取BeanMetadataElement;
  6. BeanDefinition,一个BeanDefinition对象用于描述一个bean instance,其中拥有属性值、构造器属性值以及更多由其子类提供的信息;
  7. AbstractBeanDefinition:实现了BeanDefinition接口,提供了设置和获取bean definition中的各个属性(即类的各种属性数据)
  8. AnnotatedBeanDefinition,提供接口用于获取被包装的类的元数据
  9. GenericBeanDefinition,提供parent bean的设置功能
  10. AnnotatedGenericBeanDefinition,扩展自GenericBeanDefinition,实现AnnotatedBeanDefinition提供暴露注解元数据的支持功能

注册注解配置类流程

主流程

源码分析

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
public class AnnotatedBeanDefinitionReader {

// 省略部分代码
public void registerBean(Class<?> annotatedClass, String name, Class<? extends Annotation>... qualifiers) {
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
return;
}
// 解析@Scope注解,获取bean的作用域配置信息
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
abd.setScope(scopeMetadata.getScopeName());
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
// 解析通用注解,如@Lazy等
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
// 定义qualifier信息,主要涉及到后续指定bean注入的注解@Qualifier
if (qualifiers != null) {
for (Class<? extends Annotation> qualifier : qualifiers) {
if (Primary.class == qualifier) {
abd.setPrimary(true);
}
else if (Lazy.class == qualifier) {
abd.setLazyInit(true);
}
else {
abd.addQualifier(new AutowireCandidateQualifier(qualifier));
}
}
}

BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
// 根据ScopeMetadata生成对应的Scope代理
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
// 实际bean的注入,在registry内部用一个ConcurrentHashMap持有了beandefinition信息
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}

}

解析@Scope的流程,分析spring解析注解类属性值的流程

主流程

源码分析

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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
// @Scope注解的解析器
public class AnnotationScopeMetadataResolver implements ScopeMetadataResolver {

// 解析@Scope注解,构造ScopeMetadata实例,持有bean作用域的配置信息
@Override
public ScopeMetadata resolveScopeMetadata(BeanDefinition definition) {
ScopeMetadata metadata = new ScopeMetadata();
if (definition instanceof AnnotatedBeanDefinition) {
AnnotatedBeanDefinition annDef = (AnnotatedBeanDefinition) definition;
// 获取指定注解的属性值对,此处为@Scope注解
AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(
annDef.getMetadata(), this.scopeAnnotationType);
// 如果属性不为null,则根据属性值对修改ScopeMetadata的值
if (attributes != null) {
metadata.setScopeName(attributes.getString("value"));
ScopedProxyMode proxyMode = attributes.getEnum("proxyMode");
if (proxyMode == null || proxyMode == ScopedProxyMode.DEFAULT) {
proxyMode = this.defaultProxyMode;
}
metadata.setScopedProxyMode(proxyMode);
}
}
return metadata;
}

}

// 注解配置信息的辅助工具类
public class AnnotationConfigUtils {

// 获取metadata中,annotationClass注解类型的属性值,用AnnotationAttributes(继承自LinkedHashMap,额外保存了注解类型等信息)持有
static AnnotationAttributes attributesFor(AnnotatedTypeMetadata metadata, Class<?> annotationClass) {
return attributesFor(metadata, annotationClass.getName());
}

// 获取metadata中,annotationClass注解类型的属性值,用AnnotationAttributes(继承自LinkedHashMap,额外保存了注解类型等信息)持有
static AnnotationAttributes attributesFor(AnnotatedTypeMetadata metadata, String annotationClassName) {
return AnnotationAttributes.fromMap(metadata.getAnnotationAttributes(annotationClassName, false));
}

}

// 持有类的元数据
public class StandardAnnotationMetadata extends StandardClassMetadata implements AnnotationMetadata {

// 获取指定注解名annotationName中的属性值对
@Override
public Map<String, Object> getAnnotationAttributes(String annotationName, boolean classValuesAsString) {
return (this.annotations.length > 0 ? AnnotatedElementUtils.getMergedAnnotationAttributes(
getIntrospectedClass(), annotationName, classValuesAsString, this.nestedAnnotationsAsMap) : null);
}

}

// 用于在AnnotatedElement上查找注解、元注解、可重复注解的工具类
public class AnnotatedElementUtils {

public static AnnotationAttributes getMergedAnnotationAttributes(AnnotatedElement element,
String annotationName, boolean classValuesAsString, boolean nestedAnnotationsAsMap) {

Assert.hasLength(annotationName, "'annotationName' must not be null or empty");
// 根据注解名查找注解的属性值对
AnnotationAttributes attributes = searchWithGetSemantics(element, null, annotationName,
new MergedAnnotationAttributesProcessor(classValuesAsString, nestedAnnotationsAsMap));

// 处理注解别名
AnnotationUtils.postProcessAnnotationAttributes(element, attributes, classValuesAsString, nestedAnnotationsAsMap);
return attributes;
}

private static <T> T searchWithGetSemantics(AnnotatedElement element,
Class<? extends Annotation> annotationType, String annotationName, Processor<T> processor) {
// 将查找工作,转发给processor处理(Processor -> MergedAnnotationAttributesProcessor)
return searchWithGetSemantics(element, annotationType, annotationName, null, processor);
}

private static <T> T searchWithGetSemantics(AnnotatedElement element,
Class<? extends Annotation> annotationType, String annotationName,
Class<? extends Annotation> containerType, Processor<T> processor) {

try {
// 进行第一层查找(metaDepth=0)
return searchWithGetSemantics(element, annotationType, annotationName,
containerType, processor, new HashSet<AnnotatedElement>(), 0);
}
catch (Throwable ex) {
AnnotationUtils.rethrowAnnotationConfigurationException(ex);
throw new IllegalStateException("Failed to introspect annotations on " + element, ex);
}
}

private static <T> T searchWithGetSemantics(AnnotatedElement element,
Class<? extends Annotation> annotationType, String annotationName,
Class<? extends Annotation> containerType, Processor<T> processor,
Set<AnnotatedElement> visited, int metaDepth) {

Assert.notNull(element, "AnnotatedElement must not be null");

if (visited.add(element)) {
try {
// Start searching within locally declared annotations
List<Annotation> declaredAnnotations = Arrays.asList(element.getDeclaredAnnotations());
// 转发给重载方法,进行实际的查找操作
T result = searchWithGetSemanticsInAnnotations(element, declaredAnnotations,
annotationType, annotationName, containerType, processor, visited, metaDepth);
if (result != null) {
return result;
}

if (element instanceof Class) { // otherwise getAnnotations does not return anything new
List<Annotation> inheritedAnnotations = new ArrayList<Annotation>();
for (Annotation annotation : element.getAnnotations()) {
if (!declaredAnnotations.contains(annotation)) {
inheritedAnnotations.add(annotation);
}
}

// Continue searching within inherited annotations
result = searchWithGetSemanticsInAnnotations(element, inheritedAnnotations,
annotationType, annotationName, containerType, processor, visited, metaDepth);
if (result != null) {
return result;
}
}
}
catch (Throwable ex) {
AnnotationUtils.handleIntrospectionFailure(element, ex);
}
}

return null;
}

// 执行实际的注解属性查找功能
private static <T> T searchWithGetSemanticsInAnnotations(AnnotatedElement element,
List<Annotation> annotations, Class<? extends Annotation> annotationType,
String annotationName, Class<? extends Annotation> containerType,
Processor<T> processor, Set<AnnotatedElement> visited, int metaDepth) {

// Search in annotations
// 遍历注解列表
for (Annotation annotation : annotations) {
Class<? extends Annotation> currentAnnotationType = annotation.annotationType();
// 只处理非JDK内置的注解
if (!AnnotationUtils.isInJavaLangAnnotationPackage(currentAnnotationType)) {
// 满足以下任意条件,需要调用processor.process(element, annotation, metaDepth)方法进行属性值的查找工作
// 1. 如果当前循环的注解,为我们指定的注解类型
// 2. 如果当前循环的注解,为我们指定的注解名称
// 3. 始终调用processor,即processor.alwaysProcesses()返回true
if (currentAnnotationType == annotationType ||
currentAnnotationType.getName().equals(annotationName) ||
processor.alwaysProcesses()) {
// 查找注解属性值
T result = processor.process(element, annotation, metaDepth);
if (result != null) {

if (processor.aggregates() && metaDepth == 0) {
// 聚合查找结果
processor.getAggregatedResults().add(result);
}
else {
return result;
}
}
}
// Repeatable annotations in container?
else if (currentAnnotationType == containerType) {
for (Annotation contained : getRawAnnotationsFromContainer(element, annotation)) {
T result = processor.process(element, contained, metaDepth);
if (result != null) {
// No need to post-process since repeatable annotations within a
// container cannot be composed annotations.
processor.getAggregatedResults().add(result);
}
}
}
}
}

// Recursively search in meta-annotations
for (Annotation annotation : annotations) {
Class<? extends Annotation> currentAnnotationType = annotation.annotationType();
if (!AnnotationUtils.isInJavaLangAnnotationPackage(currentAnnotationType)) {
T result = searchWithGetSemantics(currentAnnotationType, annotationType,
annotationName, containerType, processor, visited, metaDepth + 1);
if (result != null) {
processor.postProcess(element, annotation, result);
if (processor.aggregates() && metaDepth == 0) {
processor.getAggregatedResults().add(result);
}
else {
return result;
}
}
}
}

return null;
}

}

private static class MergedAnnotationAttributesProcessor implements Processor<AnnotationAttributes> {

@Override
public AnnotationAttributes process(AnnotatedElement annotatedElement, Annotation annotation, int metaDepth) {
return AnnotationUtils.retrieveAnnotationAttributes(annotatedElement, annotation,
this.classValuesAsString, this.nestedAnnotationsAsMap);
}

}


public abstract class AnnotationUtils {

// 将注解属性值包装为AnnotationAttributes,返回给上层调用
static AnnotationAttributes retrieveAnnotationAttributes(Object annotatedElement, Annotation annotation,
boolean classValuesAsString, boolean nestedAnnotationsAsMap) {

Class<? extends Annotation> annotationType = annotation.annotationType();
AnnotationAttributes attributes = new AnnotationAttributes(annotationType);

for (Method method : getAttributeMethods(annotationType)) {
try {
Object attributeValue = method.invoke(annotation);
Object defaultValue = method.getDefaultValue();
if (defaultValue != null && ObjectUtils.nullSafeEquals(attributeValue, defaultValue)) {
attributeValue = new DefaultValueHolder(defaultValue);
}
attributes.put(method.getName(),
adaptValue(annotatedElement, attributeValue, classValuesAsString, nestedAnnotationsAsMap));
}
catch (Throwable ex) {
if (ex instanceof InvocationTargetException) {
Throwable targetException = ((InvocationTargetException) ex).getTargetException();
rethrowAnnotationConfigurationException(targetException);
}
throw new IllegalStateException("Could not obtain annotation attribute value for " + method, ex);
}
}

return attributes;
}

}

基于注解配置,注册bean的原理

在spring的高版本中,官方建议开发者使用java code的配置方式。其原理主要是利用ConfigurationClassPostProcessor类来进行解析。执行的时机发生在容器启动后,调用invokeBeanFactoryPostProcessors()方法这一步。

主流程

源码分析

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
public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor,
PriorityOrdered, ResourceLoaderAware, BeanClassLoaderAware, EnvironmentAware {

public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
List<BeanDefinitionHolder> configCandidates = new ArrayList<BeanDefinitionHolder>();
String[] candidateNames = registry.getBeanDefinitionNames();

// 遍历beanfactory中所有已注册的bean
for (String beanName : candidateNames) {
BeanDefinition beanDef = registry.getBeanDefinition(beanName);
// 判断是否为处理过的full配置类
if (ConfigurationClassUtils.isFullConfigurationClass(beanDef) ||
// 判断是否为处理过的lite配置类
ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) {
if (logger.isDebugEnabled()) {
logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
}
}
// 判断是否为配置类(标注了@Configuration、@Component、@ComponentScan、@Import、@ImportResource)
// 为full配置类时,为beanDef增加键为org.springframework.context.annotation.ConfigurationClassPostProcessor.configurationClass,值为full的attribute
// 为lite配置类时,为beanDef增加键为org.springframework.context.annotation.ConfigurationClassPostProcessor.configurationClass,值为lite的attribute
else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
}
}

// Return immediately if no @Configuration classes were found
if (configCandidates.isEmpty()) {
return;
}

// Sort by previously determined @Order value, if applicable
// 配置类可以按照顺序加载
Collections.sort(configCandidates, new Comparator<BeanDefinitionHolder>() {
@Override
public int compare(BeanDefinitionHolder bd1, BeanDefinitionHolder bd2) {
int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
return (i1 < i2) ? -1 : (i1 > i2) ? 1 : 0;
}
});

// Detect any custom bean name generation strategy supplied through the enclosing application context
SingletonBeanRegistry sbr = null;
if (registry instanceof SingletonBeanRegistry) {
sbr = (SingletonBeanRegistry) registry;
if (!this.localBeanNameGeneratorSet && sbr.containsSingleton(CONFIGURATION_BEAN_NAME_GENERATOR)) {
BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(CONFIGURATION_BEAN_NAME_GENERATOR);
this.componentScanBeanNameGenerator = generator;
this.importBeanNameGenerator = generator;
}
}

// Parse each @Configuration class
ConfigurationClassParser parser = new ConfigurationClassParser(
this.metadataReaderFactory, this.problemReporter, this.environment,
this.resourceLoader, this.componentScanBeanNameGenerator, registry);

Set<BeanDefinitionHolder> candidates = new LinkedHashSet<BeanDefinitionHolder>(configCandidates);
Set<ConfigurationClass> alreadyParsed = new HashSet<ConfigurationClass>(configCandidates.size());
do {
// 解析配置类,完成这一步流程后,在其内部对各种配置信息,包装为一个ConfigurationClass的集合
// 在加载bean的过程中,实际上也是对这个集合进行各种操作,如:从@Bean方法加载bean、@Import导入配置等等
parser.parse(candidates);
parser.validate();

Set<ConfigurationClass> configClasses = new LinkedHashSet<ConfigurationClass>(parser.getConfigurationClasses());
configClasses.removeAll(alreadyParsed);

// Read the model and create bean definitions based on its content
if (this.reader == null) {
this.reader = new ConfigurationClassBeanDefinitionReader(
registry, this.sourceExtractor, this.resourceLoader, this.environment,
this.importBeanNameGenerator, parser.getImportRegistry());
}
// 对ConfigurationClassParser持有的配置信息集合进行bean的加载。
// 至此,需要注册到IOC容器的所有bean都已注册完毕
this.reader.loadBeanDefinitions(configClasses);
alreadyParsed.addAll(configClasses);

candidates.clear();
if (registry.getBeanDefinitionCount() > candidateNames.length) {
String[] newCandidateNames = registry.getBeanDefinitionNames();
Set<String> oldCandidateNames = new HashSet<String>(Arrays.asList(candidateNames));
Set<String> alreadyParsedClasses = new HashSet<String>();
for (ConfigurationClass configurationClass : alreadyParsed) {
alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
}
for (String candidateName : newCandidateNames) {
if (!oldCandidateNames.contains(candidateName)) {
BeanDefinition bd = registry.getBeanDefinition(candidateName);
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) &&
!alreadyParsedClasses.contains(bd.getBeanClassName())) {
candidates.add(new BeanDefinitionHolder(bd, candidateName));
}
}
}
candidateNames = newCandidateNames;
}
}
while (!candidates.isEmpty());

// Register the ImportRegistry as a bean in order to support ImportAware @Configuration classes
if (sbr != null) {
if (!sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
}
}

if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();
}
}

}