带着这个问题到网上搜索,大多数文章在解释这个问题的时候,上来就是@SpringBootApplication
注解中找@EnableAutoConfiguration
注解,然后找到@Import(AutoConfigurationImportSelector.class)
注解,然后就到AutoConfigurationImportSelector
类中找,惊呆😮~
不过也没错,最后确实是因为这个注解这个类完成的自动装配,但是Spring
是如何从开始的注解一步一步完成自动装配的呢?
接下来一步一步的调试跟踪,众所周知任何一个SpringBoot
项目都是从主启动类的main
方法开始的,那就从main
开始!
@SpringBootApplication
public class MySpringBootApplication {
public static void main(String[] args) {
SpringApplication.run(MySpringBootApplication.class, args);
}
}
接下来跟踪run方法,一步步来到如下run
方法:
public ConfigurableApplicationContext run(String... args) {
//StopWatch主要用来对应用启动统计耗时用的
StopWatch stopWatch = new StopWatch();
stopWatch.start();
ConfigurableApplicationContext context = null;
Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
configureHeadlessProperty();
//注册事件监听器,以便于在不同的事件发生时候,能在外部注册事件回调
SpringApplicationRunListeners listeners = getRunListeners(args);
listeners.starting();
try {
ApplicationArguments applicationArguments = new DefaultApplicationArguments(
args);
ConfigurableEnvironment environment = prepareEnvironment(listeners,
applicationArguments);
configureIgnoreBeanInfo(environment);
//项目启动时的Spring的logo就是在这里打印的
Banner printedBanner = printBanner(environment);
//创建上下文
context = createApplicationContext();
exceptionReporters = getSpringFactoriesInstances(
SpringBootExceptionReporter.class,
new Class[] { ConfigurableApplicationContext.class }, context);
//准备上下文
//1、为上下文注入系统环境、应用一些初始化器
//2、load方法加载主启动类定义信息
prepareContext(context, environment, listeners, applicationArguments,
printedBanner);
//刷新容器,跟进该方法
refreshContext(context);
afterRefresh(context, applicationArguments);
//...
return context;
}
跟随refreshContext(context)
方法,一路跟踪发现回来到Springframework
的refresh
方法,其实不用看也知道肯定会来到这里,因为整个SpringBoot就是在Spring基础之上开发的,主要就是添加了自动装配,当然,这也是这篇文章的主要目的。
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 主要功能设置一些状态flag
prepareRefresh();
// 这里是获取上面run方法中已经创建了的beanFactory
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 准备bean工厂,主要工作就是注入Spring必须的一些组件
prepareBeanFactory(beanFactory);
try {
// 这个方法在Spring层面是空实现,是留作子类定制实现
postProcessBeanFactory(beanFactory);
// 重点来了,在这里执行预先注入的BeanFactoryPostProcessors
invokeBeanFactoryPostProcessors(beanFactory);
......
}
}
跟着invokeBeanFactoryPostProcessors
进入
//实例化已经注册的BeanFactoryPostProcessor bean,并执行
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
//进入该方法
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
进入PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors())
,这个方法特别长,总得来说,这个方法的主要工作就是将已经注册到beanFactory的各种FactoryBeanPostProcessor分门别类,按照优先级有序执行。
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
// 先执行BeanDefinitionRegistryPostProcessors类型的增强器.
Set<String> processedBeans = new HashSet<>();
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
}
else {
regularPostProcessors.add(postProcessor);
}
}
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
// 首先执行实现了PriorityOrdered接口的增强器.
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
//currentRegistryProcessors内部包括一个ConfigurationClassPostProcessor,跟踪改方法
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
// 接下来执行实现了Ordered接口的增强器.
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
// 最后执行剩余的增强器.
boolean reiterate = true;
while (reiterate) {
reiterate = false;
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
reiterate = true;
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
}
// 执行增强器的回调方法
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}
......
}
跟踪上面的invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry)
方法,分别调用ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry()
方法->ConfigurationClassPostProcessor.processConfigBeanDefinitions()
方法,并且将会在``ConfigurationClassPostProcessor.processConfigBeanDefinitions`内部解析程序主启动类
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
//获取到容器中已经注入的bean信息
String[] candidateNames = registry.getBeanDefinitionNames();
//遍历容器注入的bean信息,找出所有的配置类,执行结果中会包括程序启动类()
for (String beanName : candidateNames) {
BeanDefinition beanDef = registry.getBeanDefinition(beanName);
if (ConfigurationClassUtils.isFullConfigurationClass(beanDef) ||
ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) {
if (logger.isDebugEnabled()) {
logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
}
}
else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
}
}
// 如果已注入的bean信息中没有一个 @Configuration 注解标记的类,这肯定是不合理的
if (configCandidates.isEmpty()) {
return;
}
// 将得到的所有配置类排序
configCandidates.sort((bd1, bd2) -> {
int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
return Integer.compare(i1, i2);
});
SingletonBeanRegistry sbr = null;
if (registry instanceof SingletonBeanRegistry) {
sbr = (SingletonBeanRegistry) registry;
if (!this.localBeanNameGeneratorSet) {
BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(CONFIGURATION_BEAN_NAME_GENERATOR);
if (generator != null) {
this.componentScanBeanNameGenerator = generator;
this.importBeanNameGenerator = generator;
}
}
}
if (this.environment == null) {
this.environment = new StandardEnvironment();
}
// 创建解析类,用于解析配置类
ConfigurationClassParser parser = new ConfigurationClassParser(
this.metadataReaderFactory, this.problemReporter, this.environment,
this.resourceLoader, this.componentScanBeanNameGenerator, registry);
Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
do {
//在这里真正执行解析配置类操作,解析程序主启动类, 进入该方法
parser.parse(candidates);
parser.validate();
Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
configClasses.removeAll(alreadyParsed);
......
}
}
进入parser.parse
方法:
//方法的入参是包含主启动类的BeanDefinitionHolder的一个set
public void parse(Set<BeanDefinitionHolder> configCandidates) {
this.deferredImportSelectors = new LinkedList<>();
for (BeanDefinitionHolder holder : configCandidates) {
//遍历set得到主启动类定义信息,主启动类的BeanDefinition的类型是AnnotatedBeanDefinition,所以会进入try块中的第一个if分支
BeanDefinition bd = holder.getBeanDefinition();
try {
if (bd instanceof AnnotatedBeanDefinition) {
//进入该if分支
parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());
}
else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) bd).hasBeanClass()) {
parse(((AbstractBeanDefinition) bd).getBeanClass(), holder.getBeanName());
}
else {
parse(bd.getBeanClassName(), holder.getBeanName());
}
}
catch (BeanDefinitionStoreException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanDefinitionStoreException(
"Failed to parse configuration class [" + bd.getBeanClassName() + "]", ex);
}
}
processDeferredImportSelectors();
}
上面parse方法调用链:ConfigurationClassParser.parse
-> ConfigurationClassParser.processConfigurationClass
-> ConfigurationClassParser.doProcessConfigurationClass
,来到ConfigurationClassParser.doProcessConfigurationClass
方法:
//转了一大圈,发现这个方法前缀do...才是真正干活的
protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass)
throws IOException {
// 递归处理内部类,这个方法调用一圈后又会回到当前方法,递归嘛...
processMemberClasses(configClass, sourceClass);
// 处理 @PropertySource 注解
for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(
sourceClass.getMetadata(), PropertySources.class,
org.springframework.context.annotation.PropertySource.class)) {
if (this.environment instanceof ConfigurableEnvironment) {
processPropertySource(propertySource);
}
else {
logger.warn("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() +
"]. Reason: Environment must implement ConfigurableEnvironment");
}
}
// 处理 @ComponentScan 注解,不去关注
Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
if (!componentScans.isEmpty() &&
......
}
// 处理 @Import 注解
// getImports(sourceClass),会递归地扫描类注解的继承树上所有的Import注解信息,那么其必然至少包括
// @Import(AutoConfigurationImportSelector.class) 和 @Import(AutoConfigurationPackages.Registrar.class)
processImports(configClass, sourceClass, getImports(sourceClass), true);
......
return null;
}
处理 @Import 注解完成后,当前方法返回,逆着调用链一路返回到ConfigurationClassParser.parse
方法,并继续执行processDeferredImportSelectors()
方法,此时已经将主启动类上的@Import(AutoConfigurationImportSelector.class)
得到:
private void processDeferredImportSelectors() {
//如果成员变量中的导入选择器为null,则说明不需要进行处理
//成员中的导入选择器其实是在处理@import标签时,判断如果是importSelector类型,则会放置到成员变量中。
//@SpringBootApplication->@EnableAutoConfiguration->@Import(AutoConfigurationImportSelector.class)
//所以实际上,这里的导入选择器只会是AutoConfigurationImportSelector
List<DeferredImportSelectorHolder> deferredImports = this.deferredImportSelectors;
this.deferredImportSelectors = null;
if (deferredImports == null) {
return;
}
//先进行排序
deferredImports.sort(DEFERRED_IMPORT_COMPARATOR);
//这里其实就是组->组对应的导入选择器,grouping封装了group以及List<ImportSelector>
Map<Object, DeferredImportSelectorGrouping> groupings = new LinkedHashMap<>();
Map<AnnotationMetadata, ConfigurationClass> configurationClasses = new HashMap<>();
//根据importSelector中的group进行分组
for (DeferredImportSelectorHolder deferredImport : deferredImports) {
//获取该导入选择器的组
Class<? extends Group> group = deferredImport.getImportSelector().getImportGroup();
//若该分组不存在则进行创建
DeferredImportSelectorGrouping grouping = groupings.computeIfAbsent(
(group != null ? group : deferredImport),
key -> new DeferredImportSelectorGrouping(createGroup(group)));
//将该导入选择器加入到对应的分组中
grouping.add(deferredImport);
configurationClasses.put(deferredImport.getConfigurationClass().getMetadata(),
deferredImport.getConfigurationClass());
}
//遍历执行每个分组,由于这里只有AutoConfiurationImportSelector所以我们只关注这个类即可。
for (DeferredImportSelectorGrouping grouping : groupings.values()) {
//获取需要自动装配的所有类,逐个去处理,那么如何获取则是关键。
// -1-
grouping.getImports().forEach(entry -> {
ConfigurationClass configurationClass = configurationClasses.get(entry.getMetadata());
try {
//处理自动装配的类,这里其实就是对自动装配的配置类进行处理,与处理@import的方法是一致的,感兴趣可以往里面看看。
processImports(configurationClass, asSourceClass(configurationClass),
asSourceClasses(entry.getImportClassName()), false);
}
catch (BeanDefinitionStoreException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanDefinitionStoreException(
"Failed to process import candidates for configuration class [" +
configurationClass.getMetadata().getClassName() + "]", ex);
}
});
}
}
}
1处调用链grouping.getImports()
->AutoConfigurationImportSelector.process
->AutoConfigurationImportSelector.selectImports
,这里就是selectImports
是关键:
public String[] selectImports(AnnotationMetadata annotationMetadata) {
if (!isEnabled(annotationMetadata)) {
return NO_IMPORTS;
}
AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader
.loadMetadata(this.beanClassLoader);
AnnotationAttributes attributes = getAttributes(annotationMetadata);
//就是这个方法,获取所有的候选配置类
List<String> configurations = getCandidateConfigurations(annotationMetadata,
attributes);
configurations = removeDuplicates(configurations);
Set<String> exclusions = getExclusions(annotationMetadata, attributes);
checkExcludedClasses(configurations, exclusions);
configurations.removeAll(exclusions);
configurations = filter(configurations, autoConfigurationMetadata);
fireAutoConfigurationImportEvents(configurations, exclusions);
return StringUtils.toStringArray(configurations);
}
进入方法getCandidateConfigurations
:
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata,
AnnotationAttributes attributes) {
//根据类别加载配置类信息
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;
}
其中的SpringFactoriesLoader.loadFactoryNames( getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader())
,是根据指定类别到spring.factories文件加载类,而getSpringFactoriesLoaderFactoryClass()
实现如下:
protected Class<?> getSpringFactoriesLoaderFactoryClass() {
return EnableAutoConfiguration.class;
}
在这里得到EnableAutoConfiguration
,也就是说从spring.factories文件中加载EnableAutoConfiguration
类别下的类:
这么写配置类都将被加入,然后经过排除、去重、根据配置类条件决定是否加载等操作后,剩余的类被包括,然后返回到ConfigurationClassPostProcessor.processConfigBeanDefinitions
方法中,通过loadBeanDefinitions(configClasses)
将定义信息导入。
至此,所有的满足条件的自动配置类信息都被纳入容器,然后随着容器初始化bean的生命周期,这些自动配置bean也被初始化,至此完成自动装配。