一、简易流程描述
启动类->@SpringBootApplication->@EnableAutoConfiguration-> @Import(AutoConfigurationImportSelector.class)->getCandidateConfigurations
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
// 从 Spring.factories 中 获取 EnableAutoConfiguration 下的所有类
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;
}
�getSpringFactoriesLoaderFactoryClass
protected Class<?> getSpringFactoriesLoaderFactoryClass() {
return EnableAutoConfiguration.class;
}
从 Spring.factories 中 获取 EnableAutoConfiguration 下的所有类,并进行bean的加载
二、详细描述
1、SpringApplication
primarySources 是当前传入的主类信息
mainApplicationClass 是 主类的 Class信息
2、run方法
private void prepareContext(ConfigurableApplicationContext context, ConfigurableEnvironment environment,
SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments, Banner printedBanner) {
context.setEnvironment(environment);
// 添加一些 post processing 到 context 中
postProcessApplicationContext(context);
// 在所有的初始化器中添加 context(initializer.initialize(context);)
applyInitializers(context);
// 在所有的监听器中添加 context到对应的事件中 (listener.contextPrepared(context);)
listeners.contextPrepared(context);
if (this.logStartupInfo) {
logStartupInfo(context.getParent() == null);
logStartupProfileInfo(context);
}
// Add boot specific singleton beans
// 获取spring的bean工厂,这里默认是DefaultListableBeanFactory
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
beanFactory.registerSingleton("springApplicationArguments", applicationArguments);
// beanFactory 的一些信息的设置
if (printedBanner != null) {
beanFactory.registerSingleton("springBootBanner", printedBanner);
}
if (beanFactory instanceof DefaultListableBeanFactory) {
((DefaultListableBeanFactory) beanFactory)
.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
}
if (this.lazyInitialization) {
context.addBeanFactoryPostProcessor(new LazyInitializationBeanFactoryPostProcessor());
}
// Load the sources
Set<Object> sources = getAllSources();
Assert.notEmpty(sources, "Sources must not be empty");
// 如果包含了 @Component 注解,则将启动类注册到 AnnotatedBeanDefinitionReader 中
load(context, sources.toArray(new Object[0]));
// 监听器,发布事件 (listeners.contextLoaded(context))
listeners.contextLoaded(context);
}
直接跳到 prepareContext —> getAllSources
这里获取到主类
public Set<Object> getAllSources() {
Set<Object> allSources = new LinkedHashSet<>();
// 将主类加到 set 中并返回
if (!CollectionUtils.isEmpty(this.primarySources)) {
allSources.addAll(this.primarySources);
}
if (!CollectionUtils.isEmpty(this.sources)) {
allSources.addAll(this.sources);
}
return Collections.unmodifiableSet(allSources);
}
如果包含了 @Component 注解,则将启动类注册到 AnnotatedBeanDefinitionReader 中,此时主类就会被注册到AnnotatedBeanDefinitionReader中去,内部会注册到 Beanfactory 中去。
private final AnnotatedBeanDefinitionReader annotatedReader;
// Load beans into the application context.
// source 就是主类
private int load(Class<?> source) {
if (isGroovyPresent() && GroovyBeanDefinitionSource.class.isAssignableFrom(source)) {
// Any GroovyLoaders added in beans{} DSL can contribute beans here
GroovyBeanDefinitionSource loader = BeanUtils.instantiateClass(source, GroovyBeanDefinitionSource.class);
load(loader);
}
if (isComponent(source)) {
// 如果包含了 @Component 注解,则将启动类注册到 AnnotatedBeanDefinitionReader 中
this.annotatedReader.register(source);
return 1;
}
return 0;
}
主要实现点
接着直接到refresh�Context中调用spring的refresh的invokeBeanFactoryPostProcessors方法中,(这个方法只有springboot才有实现,spring的这个方法没有实现)
这里回顾 https://www.yuque.com/wangchao-volk4/fdw9ek/ppw8cy#ObsXa
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()));
}
}
getBeanFactoryPostProcessors
�
接着 执行 invokeBeanFactoryPostProcessors—》invokeBeanDefinitionRegistryPostProcessors—》_postProcessor.postProcessBeanDefinitionRegistry(registry)—》processConfigBeanDefinitions(在方法 ConfigurationClassPostProcessor 中)
在 parser.parse(candidates)_; 方法中解析主类
接着在parse中 执行doProcessConfigurationClass
doProcessConfigurationClass 内部使用了方法 processImports
接着获取到主类中@Import中的 AutoConfigurationImportSelector.class 和AutoConfigurationPackages.Registrar.class。
doProcessConfigurationClass 执行完后回到 parser.parse(org.springframework.context.annotation.ConfigurationClassParser#parse(java.util.Set
public void parse(Set<BeanDefinitionHolder> configCandidates) {
for (BeanDefinitionHolder holder : configCandidates) {
BeanDefinition bd = holder.getBeanDefinition();
try {
if (bd instanceof AnnotatedBeanDefinition) {
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);
}
}
this.deferredImportSelectorHandler.process();
}
使用this.deferredImportSelectorHandler.process(); 处理刚才导入的@Import中的类。
process—》handler.processGroupImports()—》grouping.getImports()
�group.process(org.springframework.boot.autoconfigure.AutoConfigurationImportSelector.AutoConfigurationGroup#process)
终于找到了getCandidateConfigurations方法。
从 Spring.factories 中 获取 EnableAutoConfiguration 下的所有类。
�
�
�
�
�
�
�
�