SpringBoot源码解析(1.3.2)-自动装配原理(读取启动类注解并加载启动类bean定义)
承接上文 :https://blog.csdn.net/sql2008help/article/details/123311657
从上文得知,在 SpringApplication run方法中有一个 prepareContext 准备上下文的方法,在此方法中调用内部 this.load 方法,在 this.load 方法中创建读取配置的导入类BeanDefinitionLoader实例 loader
BeanDefinitionLoader loader = this.createBeanDefinitionLoader(this.getBeanDefinitionRegistry(context), sources);
本篇文章承接上文继续展开springboot读取注解启动类的源码解析
createBeanDefinitionLoader
protected BeanDefinitionLoader createBeanDefinitionLoader(BeanDefinitionRegistry registry, Object[] sources) {
return new BeanDefinitionLoader(registry, sources);
}
BeanDefinitionLoader 类
package org.springframework.boot;
class BeanDefinitionLoader {
private static final boolean XML_ENABLED = !SpringProperties.getFlag("spring.xml.ignore");
private static final Pattern GROOVY_CLOSURE_PATTERN = Pattern.compile(".*\\$_.*closure.*");
private final Object[] sources;
private final AnnotatedBeanDefinitionReader annotatedReader;
private final AbstractBeanDefinitionReader xmlReader;
private final BeanDefinitionReader groovyReader;
private final ClassPathBeanDefinitionScanner scanner;
private ResourceLoader resourceLoader;
BeanDefinitionLoader(BeanDefinitionRegistry registry, Object... sources) {
Assert.notNull(registry, "Registry must not be null");
Assert.notEmpty(sources, "Sources must not be empty");
this.sources = sources;
// 通过注解定义的读取器
this.annotatedReader = new AnnotatedBeanDefinitionReader(registry);
this.xmlReader = XML_ENABLED ? new XmlBeanDefinitionReader(registry) : null;
this.groovyReader = this.isGroovyPresent() ? new GroovyBeanDefinitionReader(registry) : null;
this.scanner = new ClassPathBeanDefinitionScanner(registry);
this.scanner.addExcludeFilter(new BeanDefinitionLoader.ClassExcludeFilter(sources));
}
}
AnnotatedBeanDefinitionReader
package org.springframework.context.annotation;
public class AnnotatedBeanDefinitionReader {
private final BeanDefinitionRegistry registry;
private BeanNameGenerator beanNameGenerator;
private ScopeMetadataResolver scopeMetadataResolver;
private ConditionEvaluator conditionEvaluator;
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
this(registry, getOrCreateEnvironment(registry));
}
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
this.beanNameGenerator = AnnotationBeanNameGenerator.INSTANCE;
this.scopeMetadataResolver = new AnnotationScopeMetadataResolver();
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
Assert.notNull(environment, "Environment must not be null");
this.registry = registry;
this.conditionEvaluator = new ConditionEvaluator(registry, environment, (ResourceLoader)null);
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
}
loader.load(); 方法:
注意: 从这个步骤开始正式读取自定义启动类 SpringbootDemoApplication 注解并开始加载bean定义
void load() {
Object[] var1 = this.sources;
int var2 = var1.length;
for(int var3 = 0; var3 < var2; ++var3) {
Object source = var1[var3];
this.load(source);
}
}
根据不同的配置类型执行不同的load重载方法,本例中使用类注解方式,所以执行第一个load方法
private void load(Object source) {
Assert.notNull(source, "Source must not be null");
if (source instanceof Class) {
this.load((Class)source);
} else if (source instanceof Resource) {
this.load((Resource)source);
} else if (source instanceof Package) {
this.load((Package)source);
} else if (source instanceof CharSequence) {
this.load((CharSequence)source);
} else {
throw new IllegalArgumentException("Invalid source type " + source.getClass());
}
}
通过类注解的方式加载
private void load(Class<?> source) {
if (this.isGroovyPresent() && BeanDefinitionLoader.GroovyBeanDefinitionSource.class.isAssignableFrom(source)) {
BeanDefinitionLoader.GroovyBeanDefinitionSource loader = (BeanDefinitionLoader.GroovyBeanDefinitionSource)BeanUtils.instantiateClass(source, BeanDefinitionLoader.GroovyBeanDefinitionSource.class);
((GroovyBeanDefinitionReader)this.groovyReader).beans(loader.getBeans());
}
if (this.isEligible(source)) {
// 执行注册方法
this.annotatedReader.register(new Class[]{source});
}
}
public void register(Class<?>... componentClasses) {
Class[] var2 = componentClasses;
int var3 = componentClasses.length;
for(int var4 = 0; var4 < var3; ++var4) {
Class<?> componentClass = var2[var4];
this.registerBean(componentClass);
}
}
public void registerBean(Class<?> beanClass) {
this.doRegisterBean(beanClass, (String)null, (Class[])null, (Supplier)null, (BeanDefinitionCustomizer[])null);
}
private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name, @Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier, @Nullable BeanDefinitionCustomizer[] customizers) {
// 注意区分BeanDefinition类型,这里是未注册的可注解的bean定义类型
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
// 如果配置了 @Conditional 则判断条件是否满足
if (!this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
abd.setInstanceSupplier(supplier);
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
abd.setScope(scopeMetadata.getScopeName());
String beanName = name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry);
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
int var10;
int var11;
if (qualifiers != null) {
Class[] var9 = qualifiers;
var10 = qualifiers.length;
for(var11 = 0; var11 < var10; ++var11) {
Class<? extends Annotation> qualifier = var9[var11];
if (Primary.class == qualifier) {
abd.setPrimary(true);
} else if (Lazy.class == qualifier) {
abd.setLazyInit(true);
} else {
abd.addQualifier(new AutowireCandidateQualifier(qualifier));
}
}
}
if (customizers != null) {
BeanDefinitionCustomizer[] var13 = customizers;
var10 = customizers.length;
for(var11 = 0; var11 < var10; ++var11) {
BeanDefinitionCustomizer customizer = var13[var11];
customizer.customize(abd);
}
}
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
// 往 beanFactory 中注册bean定义(即往beanDefinitionMap中添加新的定义)
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
}
执行完prepareContext方法后,beanFactory 中 bean定义 beanDefinitionMap 如下: