我是靠谱客的博主 辛勤跳跳糖,这篇文章主要介绍深入剖析Spring boot自动装配原理三(@EnableAutoConfiguration),现在分享给大家,希望可以做个参考。

概要

何为自动装配?自动装配可简单理解为Spring自动读取配置类信息,并解析配置类中的Bean信息,然后将相关Bean初始化到IOC容器中。前面两个章节已经了解了SPI技术和Spring中Import注解的实现原理,本章节来具体讲解Spring boot如何使用通过EnableAutoConfiguration注解将Bean自动注入到Spring容器中。

源码剖析

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

Spring Boot将相关配置都集成到了SpringBootApplication注解,在启动类加上该注解则标识为Spring Boot应用,进入SpringBootApplication类可以看到该类集成了@SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan三个注解,SpringBootConfiguration继承了@Configuration,标识该类为Spring的配置类,在Spring启动IOC容器的时候可以识别并解析,ComponentScan表示IOC容器启动时,需要去扫描注册的Spring组件,EnableAutoConfiguration即标识开启Spring Boot 自动配置,进入之后发现其主要包含了两个注解,一个为AutoConfigurationPackage,另一个为Import,AutoConfigurationPackage默认没有扫描的包路径暂忽略,Import注解导入了AutoConfigurationImportSelector,该类为Spring Boot自动装配核心类,通过该类自动装载了Spring Boot需要的对象到IOC,下面对该类进行重点讲解。

首先上源码

AutoConfigurationImportSelector

复制代码
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
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
.public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware, ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered { private static final AutoConfigurationEntry EMPTY_ENTRY = new AutoConfigurationEntry(); private static final String[] NO_IMPORTS = {}; private static final Log logger = LogFactory.getLog(AutoConfigurationImportSelector.class); private static final String PROPERTY_NAME_AUTOCONFIGURE_EXCLUDE = "spring.autoconfigure.exclude"; private ConfigurableListableBeanFactory beanFactory; private Environment environment; // 类加载器(AppClassLoader) private ClassLoader beanClassLoader; private ResourceLoader resourceLoader; private ConfigurationClassFilter configurationClassFilter; @Override // 获取需要自动装载的Bean的classname集合 // ConfigurationClassPostProcessor解析配置类的时候会调用该方法 public String[] selectImports(AnnotationMetadata annotationMetadata) { // 是否需要导入类,默认需要,不会进入此判断 if (!isEnabled(annotationMetadata)) { return NO_IMPORTS; } // 获取自动装配对象(里面包含需要解析的配置类) AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(annotationMetadata); // 返回自动装配Bean的classname集合 return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations()); } @Override public Predicate<String> getExclusionFilter() { return this::shouldExclude; } private boolean shouldExclude(String configurationClassName) { return getConfigurationClassFilter().filter(Collections.singletonList(configurationClassName)).isEmpty(); } /** * Return the {@link AutoConfigurationEntry} based on the {@link AnnotationMetadata} * of the importing {@link Configuration @Configuration} class. * @param annotationMetadata the annotation metadata of the configuration class * @return the auto-configurations that should be imported */ protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) { if (!isEnabled(annotationMetadata)) { return EMPTY_ENTRY; } // 获取配置类所有注解属性,此处传入的类为EnableAutoConfiguration,获取到exclude和excludeName属性 AnnotationAttributes attributes = getAttributes(annotationMetadata); // 获取配置类标注的所有候选配置类信息 List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes); // 去除重复项 configurations = removeDuplicates(configurations); // 获取需要排除的配置类(不需要注入容器的Bean) Set<String> exclusions = getExclusions(annotationMetadata, attributes); // 检查排除的配置类的合法性,如果不合法则抛出异常 checkExcludedClasses(configurations, exclusions); // 从需要解析的配置类集合中剔除需要排除的配置类 configurations.removeAll(exclusions); // 获取配置类过滤器对配置类进行过滤 configurations = getConfigurationClassFilter().filter(configurations); // 开启记录自动化配置过程中条件匹配的详细信息及日志信息 fireAutoConfigurationImportEvents(configurations, exclusions); return new AutoConfigurationEntry(configurations, exclusions); } @Override public Class<? extends Group> getImportGroup() { return AutoConfigurationGroup.class; } protected boolean isEnabled(AnnotationMetadata metadata) { if (getClass() == AutoConfigurationImportSelector.class) { return getEnvironment().getProperty(EnableAutoConfiguration.ENABLED_OVERRIDE_PROPERTY, Boolean.class, true); } return true; } // 获取注解的所有属性 protected AnnotationAttributes getAttributes(AnnotationMetadata metadata) { String name = getAnnotationClass().getName(); AnnotationAttributes attributes = AnnotationAttributes.fromMap(metadata.getAnnotationAttributes(name, true)); Assert.notNull(attributes, () -> "No auto-configuration attributes found. Is " + metadata.getClassName() + " annotated with " + ClassUtils.getShortName(name) + "?"); return attributes; } /** * Return the source annotation class used by the selector. * @return the annotation class */ protected Class<?> getAnnotationClass() { return EnableAutoConfiguration.class; } /** * Return the auto-configuration class names that should be considered. By default * this method will load candidates using {@link SpringFactoriesLoader} with * {@link #getSpringFactoriesLoaderFactoryClass()}. * @param metadata the source metadata * @param attributes the {@link #getAttributes(AnnotationMetadata) annotation * attributes} * @return a list of candidate configurations */ protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) { /** * 通过SpringFactoriesLoader去所有jar包中META-INF/spring.factories路径下获取 * 标注key为org.springframework.boot.autoconfigure.EnableAutoConfiguration(getSpringFactoriesLoaderFactoryClass返回值)的所有配置类。 * org.springframework.boot.autoconfigure.EnableAutoConfiguration= * org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration, * org.springframework.boot.autoconfigure.aop.AopAutoConfiguration, * org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration, * SpringFactoriesLoader.loadFactoryNames运用SPI的机制读取文件内容(不清楚SPI可以参考第一章节) **/ List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader()); Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you " + "are using a custom packaging, make sure that file is correct."); return configurations; } /** * Return the class used by {@link SpringFactoriesLoader} to load configuration * candidates. * @return the factory class */ protected Class<?> getSpringFactoriesLoaderFactoryClass() { return EnableAutoConfiguration.class; } private void checkExcludedClasses(List<String> configurations, Set<String> exclusions) { // 如果排除的配置类能能正常加载,并且在自动装配的配置类集合中不存在,则添加到非验证的排除类集合中 List<String> invalidExcludes = new ArrayList<>(exclusions.size()); for (String exclusion : exclusions) { // 检验类能否加载 if (ClassUtils.isPresent(exclusion, getClass().getClassLoader()) && !configurations.contains(exclusion)) { invalidExcludes.add(exclusion); } } // 非验证的排除类集合不为空的话抛出异常 if (!invalidExcludes.isEmpty()) { handleInvalidExcludes(invalidExcludes); } } /** * Handle any invalid excludes that have been specified. * @param invalidExcludes the list of invalid excludes (will always have at least one * element) */ protected void handleInvalidExcludes(List<String> invalidExcludes) { StringBuilder message = new StringBuilder(); for (String exclude : invalidExcludes) { message.append("t- ").append(exclude).append(String.format("%n")); } throw new IllegalStateException(String.format( "The following classes could not be excluded because they are not auto-configuration classes:%n%s", message)); } /** * Return any exclusions that limit the candidate configurations. * @param metadata the source metadata * @param attributes the {@link #getAttributes(AnnotationMetadata) annotation * attributes} * @return exclusions or an empty set */ protected Set<String> getExclusions(AnnotationMetadata metadata, AnnotationAttributes attributes) { Set<String> excluded = new LinkedHashSet<>(); excluded.addAll(asList(attributes, "exclude")); excluded.addAll(Arrays.asList(attributes.getStringArray("excludeName"))); excluded.addAll(getExcludeAutoConfigurationsProperty()); return excluded; } /** * Returns the auto-configurations excluded by the * {@code spring.autoconfigure.exclude} property. * @return excluded auto-configurations * @since 2.3.2 */ protected List<String> getExcludeAutoConfigurationsProperty() { Environment environment = getEnvironment(); if (environment == null) { return Collections.emptyList(); } if (environment instanceof ConfigurableEnvironment) { Binder binder = Binder.get(environment); return binder.bind(PROPERTY_NAME_AUTOCONFIGURE_EXCLUDE, String[].class).map(Arrays::asList) .orElse(Collections.emptyList()); } String[] excludes = environment.getProperty(PROPERTY_NAME_AUTOCONFIGURE_EXCLUDE, String[].class); return (excludes != null) ? Arrays.asList(excludes) : Collections.emptyList(); } protected List<AutoConfigurationImportFilter> getAutoConfigurationImportFilters() { return SpringFactoriesLoader.loadFactories(AutoConfigurationImportFilter.class, this.beanClassLoader); } private ConfigurationClassFilter getConfigurationClassFilter() { if (this.configurationClassFilter == null) { /** * 获取配置类过滤器 * 通过SpringFactoriesLoader去所有jar包中(此处为spring-boot-autoconfigure jar包)META-INF/spring.factories中 * 标注key为oorg.springframework.boot.autoconfigure.AutoConfigurationImportFilter的所有过滤器 * org.springframework.boot.autoconfigure.AutoConfigurationImportFilter= * org.springframework.boot.autoconfigure.condition.OnBeanCondition, * org.springframework.boot.autoconfigure.condition.OnClassCondition, * org.springframework.boot.autoconfigure.condition.OnWebApplicationCondition * 这些类作用于Conditional开头的注解,例如ConditionalOnBean、ConditionalOnMissingBean、ConditionalOnMissingClass等 */ List<AutoConfigurationImportFilter> filters = getAutoConfigurationImportFilters(); for (AutoConfigurationImportFilter filter : filters) { // 调用Aware接口方法,将相关属性设置到Aware实现类的属性中, //此处是将容器的工厂设置到过滤器的beanFactory属性中 invokeAwareMethods(filter); } this.configurationClassFilter = new ConfigurationClassFilter(this.beanClassLoader, filters); } return this.configurationClassFilter; } // 通过set去重 protected final <T> List<T> removeDuplicates(List<T> list) { return new ArrayList<>(new LinkedHashSet<>(list)); } protected final List<String> asList(AnnotationAttributes attributes, String name) { String[] value = attributes.getStringArray(name); return Arrays.asList(value); } private void fireAutoConfigurationImportEvents(List<String> configurations, Set<String> exclusions) { /** * 通过SpringFactoriesLoader去所有jar包中(此处为spring-boot-autoconfigure jar包)META-INF/spring.factories中 * 标注key为oorg.springframework.boot.autoconfigure.AutoConfigurationImportListener的所有监听器 * org.springframework.boot.autoconfigure.AutoConfigurationImportListener= * org.springframework.boot.autoconfigure.condition.ConditionEvaluationReportAutoConfigurationImportListener */ List<AutoConfigurationImportListener> listeners = getAutoConfigurationImportListeners(); if (!listeners.isEmpty()) { AutoConfigurationImportEvent event = new AutoConfigurationImportEvent(this, configurations, exclusions); for (AutoConfigurationImportListener listener : listeners) { // 调用Aware接口方法,将相关属性设置到Aware实现类的属性中, //此处是将容器的工厂设置到过滤器的beanFactory属性中 invokeAwareMethods(listener); listener.onAutoConfigurationImportEvent(event); } } } protected List<AutoConfigurationImportListener> getAutoConfigurationImportListeners() { return SpringFactoriesLoader.loadFactories(AutoConfigurationImportListener.class, this.beanClassLoader); } private void invokeAwareMethods(Object instance) { if (instance instanceof Aware) { // 设置Bean的类装载器 if (instance instanceof BeanClassLoaderAware) { ((BeanClassLoaderAware) instance).setBeanClassLoader(this.beanClassLoader); } // 设置Bean工厂 if (instance instanceof BeanFactoryAware) { ((BeanFactoryAware) instance).setBeanFactory(this.beanFactory); } // if (instance instanceof EnvironmentAware) { ((EnvironmentAware) instance).setEnvironment(this.environment); } // 设置资源加载器 if (instance instanceof ResourceLoaderAware) { ((ResourceLoaderAware) instance).setResourceLoader(this.resourceLoader); } } } ...... private static class ConfigurationClassFilter { private final AutoConfigurationMetadata autoConfigurationMetadata; private final List<AutoConfigurationImportFilter> filters; ConfigurationClassFilter(ClassLoader classLoader, List<AutoConfigurationImportFilter> filters) { this.autoConfigurationMetadata = AutoConfigurationMetadataLoader.loadMetadata(classLoader); this.filters = filters; } // 将不符合的配置类剔除,例如配置了ConditionalOnMissingClass,则表示ConditionalOnMissingClass注解中配置的类不存在才会加载当前类 List<String> filter(List<String> configurations) { long startTime = System.nanoTime(); String[] candidates = StringUtils.toStringArray(configurations); boolean skipped = false; for (AutoConfigurationImportFilter filter : this.filters) { /** * 对需要加载的配置类进行过滤处理, * 处理配置了Conditional开头的注解的配置类, * 具体过滤规则可阅读FilteringSpringBootCondition的match方法 */ boolean[] match = filter.match(candidates, this.autoConfigurationMetadata); for (int i = 0; i < match.length; i++) { // 如果过滤规则匹配成功,则将配置类删除(数组元素赋空) if (!match[i]) { candidates[i] = null; skipped = true; } } } // 匹配不到返回原配置类集合 if (!skipped) { return configurations; } // 将空的配置类删除,并返回删除之后的配置类集合 List<String> result = new ArrayList<>(candidates.length); for (String candidate : candidates) { if (candidate != null) { result.add(candidate); } } if (logger.isTraceEnabled()) { int numberFiltered = configurations.size() - result.size(); logger.trace("Filtered " + numberFiltered + " auto configuration class in " + TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startTime) + " ms"); } return result; } } private static class AutoConfigurationGroup implements DeferredImportSelector.Group, BeanClassLoaderAware, BeanFactoryAware, ResourceLoaderAware { private final Map<String, AnnotationMetadata> entries = new LinkedHashMap<>(); private final List<AutoConfigurationEntry> autoConfigurationEntries = new ArrayList<>(); ...... @Override public void process(AnnotationMetadata annotationMetadata, DeferredImportSelector deferredImportSelector) { Assert.state(deferredImportSelector instanceof AutoConfigurationImportSelector, () -> String.format("Only %s implementations are supported, got %s", AutoConfigurationImportSelector.class.getSimpleName(), deferredImportSelector.getClass().getName())); // 获取自动装配对象(里面包含需要解析的配置类) AutoConfigurationEntry autoConfigurationEntry = ((AutoConfigurationImportSelector) deferredImportSelector) .getAutoConfigurationEntry(annotationMetadata); this.autoConfigurationEntries.add(autoConfigurationEntry); for (String importClassName : autoConfigurationEntry.getConfigurations()) { this.entries.putIfAbsent(importClassName, annotationMetadata); } } @Override public Iterable<Entry> selectImports() { if (this.autoConfigurationEntries.isEmpty()) { return Collections.emptyList(); } // 获取需要排除的类 Set<String> allExclusions = this.autoConfigurationEntries.stream() .map(AutoConfigurationEntry::getExclusions).flatMap(Collection::stream).collect(Collectors.toSet()); // 获取所有需要解析的配置类 Set<String> processedConfigurations = this.autoConfigurationEntries.stream() .map(AutoConfigurationEntry::getConfigurations).flatMap(Collection::stream) .collect(Collectors.toCollection(LinkedHashSet::new)); // 移除不需要处理的配置类 processedConfigurations.removeAll(allExclusions); return sortAutoConfigurations(processedConfigurations, getAutoConfigurationMetadata()).stream() .map((importClassName) -> new Entry(this.entries.get(importClassName), importClassName)) .collect(Collectors.toList()); } private AutoConfigurationMetadata getAutoConfigurationMetadata() { if (this.autoConfigurationMetadata == null) { this.autoConfigurationMetadata = AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader); } return this.autoConfigurationMetadata; } private List<String> sortAutoConfigurations(Set<String> configurations, AutoConfigurationMetadata autoConfigurationMetadata) { return new AutoConfigurationSorter(getMetadataReaderFactory(), autoConfigurationMetadata) .getInPriorityOrder(configurations); } private MetadataReaderFactory getMetadataReaderFactory() { try { return this.beanFactory.getBean(SharedMetadataReaderFactoryContextInitializer.BEAN_NAME, MetadataReaderFactory.class); } catch (NoSuchBeanDefinitionException ex) { return new CachingMetadataReaderFactory(this.resourceLoader); } } } protected static class AutoConfigurationEntry { private final List<String> configurations; private final Set<String> exclusions; private AutoConfigurationEntry() { this.configurations = Collections.emptyList(); this.exclusions = Collections.emptySet(); } /** * Create an entry with the configurations that were contributed and their * exclusions. * @param configurations the configurations that should be imported * @param exclusions the exclusions that were applied to the original list */ AutoConfigurationEntry(Collection<String> configurations, Collection<String> exclusions) { this.configurations = new ArrayList<>(configurations); this.exclusions = new HashSet<>(exclusions); } public List<String> getConfigurations() { return this.configurations; } public Set<String> getExclusions() { return this.exclusions; } } }

由于AutoConfigurationImportSelector实现了DeferredImportSelector(延迟导入)接口,其自动装配会经过ConfigurationClassParser进行后置处理(this.deferredImportSelectorHandler.process(),通过ConfigurationClassParserKaTeX parse error: Expected 'EOF', got '#' at position 30: …SelectorHandler#̲process方法处理)。 D…Group(即不能的选择器分配到不同的组),然后调用分组内部方法process(DeferredImportSelectorKaTeX parse error: Expected 'EOF', got '#' at position 6: Group#̲process)解析META-…Group#selectImports)返回需要进行自动装配的配置类实体集合,之后交给ConfigurationClassParser#processImports进行解析。

复制代码
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
private class DeferredImportSelectorHandler { @Nullable private List<DeferredImportSelectorHolder> deferredImportSelectors = new ArrayList<>(); ...... // 延迟导入选择器后置解析入口 public void process() { List<DeferredImportSelectorHolder> deferredImports = this.deferredImportSelectors; this.deferredImportSelectors = null; try { if (deferredImports != null) { DeferredImportSelectorGroupingHandler handler = new DeferredImportSelectorGroupingHandler(); // 排序 deferredImports.sort(DEFERRED_IMPORT_COMPARATOR); // 循环调用DeferredImportSelectorGroupingHandler#register方法,将选择器分组信息注入 deferredImports.forEach(handler::register); // 调用DeferredImportSelectorGroupingHandler#processGroupImports方法处理组内需要导入的配置类 handler.processGroupImports(); } } finally { this.deferredImportSelectors = new ArrayList<>(); } } } private class DeferredImportSelectorGroupingHandler { private final Map<Object, DeferredImportSelectorGrouping> groupings = new LinkedHashMap<>(); private final Map<AnnotationMetadata, ConfigurationClass> configurationClasses = new HashMap<>(); public void register(DeferredImportSelectorHolder deferredImport) { // 调用DeferredImportSelector#getImportGroup方法获取分组信息 // AutoConfigurationImportSelector#getImportGroup Class<? extends Group> group = deferredImport.getImportSelector().getImportGroup(); // 如果groupings集合中存在当前分组则直接返回分组信息,否则存入结合再返回 DeferredImportSelectorGrouping grouping = this.groupings.computeIfAbsent( (group != null ? group : deferredImport), key -> new DeferredImportSelectorGrouping(createGroup(group))); // 延迟导入选择器分组对象存入当前延迟导入选择器处理Bean,等待回调选择器的process方法的时候传入 // AutoConfigurationImportSelector$AutoConfigurationGroup#process(AnnotationMetadata annotationMetadata, DeferredImportSelector deferredImportSelector) // 此处的deferredImportSelector为AutoConfigurationImportSelector grouping.add(deferredImport); this.configurationClasses.put(deferredImport.getConfigurationClass().getMetadata(), deferredImport.getConfigurationClass()); } public void processGroupImports() { for (DeferredImportSelectorGrouping grouping : this.groupings.values()) { Predicate<String> exclusionFilter = grouping.getCandidateFilter(); grouping.getImports().forEach(entry -> { ConfigurationClass configurationClass = this.configurationClasses.get(entry.getMetadata()); try { // 递归解析需要注入的配置类 processImports(configurationClass, asSourceClass(configurationClass, exclusionFilter), Collections.singleton(asSourceClass(entry.getImportClassName(), exclusionFilter)), exclusionFilter, false); } ...... }); } } ...... } private static class DeferredImportSelectorGrouping { ...... public Iterable<Group.Entry> getImports() { for (DeferredImportSelectorHolder deferredImport : this.deferredImports) { // 调用后置导入选择器分组process方法(AutoConfigurationImportSelector$AutoConfigurationGroup#process,获取需要装载的配置类集合) this.group.process(deferredImport.getConfigurationClass().getMetadata(), deferredImport.getImportSelector()); } // 调用后置导入选择器分组selectImports方法返回需要装载的配置类实体集合 return this.group.selectImports(); } ...... }

ImportSelector是直接调用ImportSelector#selectImports方法,获取需要自动装配的配置类classname集合,之后交给ConfigurationClassParser#processImports进行解析。

总结:

Spring Boot自动装配的流程是先通过SpringApplication将@SpringApplication注解类注入到Spring IOC容器,然后通过ConfigurationClassParser对标注@Configuration的类进行解析,当解析到@EnableAutoConfiguration注解的时候,发现其内部通过Import注解导入了AutoConfigurationImportSelector类,ConfigurationClassParser通过processImports方法去解析AutoConfigurationImportSelector。AutoConfigurationImportSelector通过selectImports方法运用SPI机制获取Spring Boot所有jar包内META-INF/spring.factories文件内路径标注key为org.springframework.boot.autoconfigure.EnableAutoConfiguration的配置类,然后通过一些列的excludeFilter排除相关配置类,获取到相关配置类之后,交由ConfigurationClassParser解析出来,并存入Spring IOC容器对应BeanFactory的beanDefinitionMap中,最终通过DefaultListableBeanFactory#preInstantiateSingletons进行实例化,该过程就将Spring Boot的一些Bean自动注入到了Spring IOC容器中。

最后

以上就是辛勤跳跳糖最近收集整理的关于深入剖析Spring boot自动装配原理三(@EnableAutoConfiguration)的全部内容,更多相关深入剖析Spring内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(60)

评论列表共有 0 条评论

立即
投稿
返回
顶部