SpringBoot刷新上下文一共七篇,基于SpringBoot 2.2.7.RELEASE,Spring 5.2.6.RELEASE
SpringBoot 刷新上下文1–主流程
SpringBoot 刷新上下文2–执行BeanDefinitionRegistryPostProcessor
SpringBoot 刷新上下文3–解析引导类
SpringBoot 刷新上下文4–处理ComponentScan
SpringBoot 刷新上下文5–处理其他注解
SpringBoot 刷新上下文6–加载并注册BeanDefinition
SpringBoot 刷新上下文7–执行BeanFactoryPostProcessor
2.1.3.1.2、处理其他注解
2.1.3.1.2.1、处理配置类内部的类
//org.springframework.context.annotation.ConfigurationClassParser#processMemberClasses
private void processMemberClasses(ConfigurationClass configClass, SourceClass sourceClass, Predicate<String> filter) throws IOException {
//获取引导类的内部类,这里会递归处理
Collection<SourceClass> memberClasses = sourceClass.getMemberClasses();
if (!memberClasses.isEmpty()) {
List<SourceClass> candidates = new ArrayList<>(memberClasses.size());
//获取内部类是配置类的类
for (SourceClass memberClass : memberClasses) {
if (ConfigurationClassUtils.isConfigurationCandidate(memberClass.getMetadata()) &&
!memberClass.getMetadata().getClassName().equals(configClass.getMetadata().getClassName())) {
candidates.add(memberClass);
}
}
//排序
OrderComparator.sort(candidates);
//遍历
for (SourceClass candidate : candidates) {
// 处理 error warn的类
if (this.importStack.contains(configClass)) {
this.problemReporter.error(new CircularImportProblem(configClass, this.importStack));
}
else {
this.importStack.push(configClass);
try {
//处理内部类是配置类的类 递归了
processConfigurationClass(candidate.asConfigClass(configClass), filter);
}
finally {
this.importStack.pop();
}
}
}
}
}
2.1.3.1.2.2、处理@PropertySource
//org.springframework.context.annotation.ConfigurationClassParser#processPropertySource
private void processPropertySource(AnnotationAttributes propertySource) throws IOException {
// 获取资源name
String name = propertySource.getString("name");
if (!StringUtils.hasLength(name)) {
name = null;
}
// 获取 encoding
String encoding = propertySource.getString("encoding");
if (!StringUtils.hasLength(encoding)) {
encoding = null;
}
// 获取 配置的值,资源的位置
String[] locations = propertySource.getStringArray("value");
Assert.isTrue(locations.length > 0, "At least one @PropertySource(value) location is required");
boolean ignoreResourceNotFound = propertySource.getBoolean("ignoreResourceNotFound");
Class<? extends PropertySourceFactory> factoryClass = propertySource.getClass("factory");
PropertySourceFactory factory = (factoryClass == PropertySourceFactory.class ?
DEFAULT_PROPERTY_SOURCE_FACTORY : BeanUtils.instantiateClass(factoryClass));
//遍历所有 配置的资源路径
for (String location : locations) {
try {
//解析占位符,获取真实路径
String resolvedLocation = this.environment.resolveRequiredPlaceholders(location);
//读取资源
Resource resource = this.resourceLoader.getResource(resolvedLocation);
//创建PropertySource并添加到Environment的propertiSources
addPropertySource(factory.createPropertySource(name, new EncodedResource(resource, encoding)));
}
catch (IllegalArgumentException | FileNotFoundException | UnknownHostException ex) {
...
}
}
}
2.1.3.1.2.3、处理@Import
这里默认会得到引导类 @SpringBootApplication 注解中 @EnableAutoConfigration 注解中配置的类,这个注解前面讲过,不再陈述解析过程。
//org.springframework.context.annotation.ConfigurationClassParserprocessImports
private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass, Collection<SourceClass> importCandidates, Predicate<String> exclusionFilter, boolean checkForCircularImports) {
if (importCandidates.isEmpty()) {
return;
}
if (checkForCircularImports && isChainedImportOnStack(configClass)) {
this.problemReporter.error(new CircularImportProblem(configClass, this.importStack));
}
else {
this.importStack.push(configClass);
try {
//遍历扫描到的 @Import 导入的类
for (SourceClass candidate : importCandidates) {
//导入类是否派生自 ImportSelector
if (candidate.isAssignable(ImportSelector.class)) {
// Candidate class is an ImportSelector -> delegate to it to determine imports
//获取候选类的 class
Class<?> candidateClass = candidate.loadClass();
//加载候选类
ImportSelector selector = ParserStrategyUtils.instantiateClass(candidateClass, ImportSelector.class,
this.environment, this.resourceLoader, this.registry);
Predicate<String> selectorFilter = selector.getExclusionFilter();
if (selectorFilter != null) {
exclusionFilter = exclusionFilter.or(selectorFilter);
}
//@EnableAutoConfigration 注解上配置类在这里处理,导入自动装配
// AutoConfigurationImportSelector
if (selector instanceof DeferredImportSelector) {
//将实现DeferredImportSelector的类加入
this.deferredImportSelectorHandler.handle(configClass, (DeferredImportSelector) selector);
}
else {
//执行候选类的 selectImports 方法获取要导入的类
String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());
Collection<SourceClass> importSourceClasses = asSourceClasses(importClassNames, exclusionFilter);
//递归处理
processImports(configClass, currentSourceClass, importSourceClasses, exclusionFilter, false);
}
}
//是否派生自 ImportBeanDefinitionRegistrar
//class org.springframework.boot.autoconfigure.AutoConfigurationPackages$Registrar
//@EnableAutoConfiguration 注解上标的类,获取扫描包
else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) {
// Candidate class is an ImportBeanDefinitionRegistrar ->
// delegate to it to register additional bean definitions
Class<?> candidateClass = candidate.loadClass();
ImportBeanDefinitionRegistrar registrar =
ParserStrategyUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class,
this.environment, this.resourceLoader, this.registry);
configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata());
}
else {
// Candidate class not an ImportSelector or ImportBeanDefinitionRegistrar ->
// process it as an @Configuration class
// 导入类不是ImportSelector 或 ImportBeanDefinitionRegistrar,
// 按配置类处理
this.importStack.registerImport(
currentSourceClass.getMetadata(), candidate.getMetadata().getClassName());
//导入的其他类,递归处理
processConfigurationClass(candidate.asConfigClass(configClass), exclusionFilter);
}
}
}
catch (BeanDefinitionStoreException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanDefinitionStoreException(
"Failed to process import candidates for configuration class [" +
configClass.getMetadata().getClassName() + "]", ex);
}
finally {
this.importStack.pop();
}
}
}
将实现DeferredImportSelector的类加入集合
private List<DeferredImportSelectorHolder> deferredImportSelectors = new ArrayList<>();
//org.springframework.context.annotation.ConfigurationClassParser.DeferredImportSelectorHandler#handle
public void handle(ConfigurationClass configClass, DeferredImportSelector importSelector) {
DeferredImportSelectorHolder holder = new DeferredImportSelectorHolder(configClass, importSelector);
if (this.deferredImportSelectors == null) {
DeferredImportSelectorGroupingHandler handler = new DeferredImportSelectorGroupingHandler();
handler.register(holder);
handler.processGroupImports();
}
else {
//加入
this.deferredImportSelectors.add(holder);
}
}
2.1.3.1.2.4、处理@Bean
private final MetadataReaderFactory metadataReaderFactory;
//org.springframework.context.annotation.ConfigurationClassParser#retrieveBeanMethodMetadata
private Set<MethodMetadata> retrieveBeanMethodMetadata(SourceClass sourceClass) {
//获取类注解
AnnotationMetadata original = sourceClass.getMetadata();
//获取@Bean 标注的所有方法
Set<MethodMetadata> beanMethods = original.getAnnotatedMethods(Bean.class.getName());
if (beanMethods.size() > 1 && original instanceof StandardAnnotationMetadata) {
// Try reading the class file via ASM for deterministic declaration order...
// Unfortunately, the JVM's standard reflection returns methods in arbitrary
// order, even between different runs of the same application on the same JVM.
try {
AnnotationMetadata asm =
this.metadataReaderFactory.getMetadataReader(original.getClassName()).getAnnotationMetadata();
Set<MethodMetadata> asmMethods = asm.getAnnotatedMethods(Bean.class.getName());
if (asmMethods.size() >= beanMethods.size()) {
Set<MethodMetadata> selectedMethods = new LinkedHashSet<>(asmMethods.size());
for (MethodMetadata asmMethod : asmMethods) {
for (MethodMetadata beanMethod : beanMethods) {
if (beanMethod.getMethodName().equals(asmMethod.getMethodName())) {
selectedMethods.add(beanMethod);
break;
}
}
}
if (selectedMethods.size() == beanMethods.size()) {
// All reflection-detected methods found in ASM method set -> proceed
beanMethods = selectedMethods;
}
}
}
catch (IOException ex) {
logger.debug("Failed to read class file via ASM for determining @Bean method order", ex);
// No worries, let's continue with the reflection metadata we started with...
}
}
return beanMethods;
}
2.1.3.1.2.5、处理接口的默认方法
//org.springframework.context.annotation.ConfigurationClassParser#processInterfaces
private void processInterfaces(ConfigurationClass configClass, SourceClass sourceClass) throws IOException {
for (SourceClass ifc : sourceClass.getInterfaces()) {
//调用上面的方法,获取接口默认方法作为@Bean标注方法的方法
Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(ifc);
for (MethodMetadata methodMetadata : beanMethods) {
if (!methodMetadata.isAbstract()) {
// A default method or other concrete method on a Java 8+ interface...
configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
}
}
//递归
processInterfaces(configClass, ifc);
}
}