入口
BeanDefinitionLoader顾名思义是用来加载bean定义的。在spring boot启动过程中的准备上下文件阶段会进行source关联资源的bean定义加载,为后续bean的实例化做准备。关键代码如下:
java
//SpringApplication
public class SpringApplication {
//...
private void prepareContext(...) {
//...
f (!AotDetector.useGeneratedArtifacts()) {
// Load the sources
Set<Object> sources = getAllSources();
Assert.notEmpty(sources, "Sources must not be empty");
load(context, sources.toArray(new Object[0]));
}
//....
}
protected void load(ApplicationContext context, Object[] sources) {
if (logger.isDebugEnabled()) {
logger.debug("Loading source " + StringUtils.arrayToCommaDelimitedString(sources));
}
BeanDefinitionLoader loader = createBeanDefinitionLoader(getBeanDefinitionRegistry(context), sources);
if (this.beanNameGenerator != null) {
loader.setBeanNameGenerator(this.beanNameGenerator);
}
if (this.resourceLoader != null) {
loader.setResourceLoader(this.resourceLoader);
}
if (this.environment != null) {
loader.setEnvironment(this.environment);
}
loader.load();
}
//...
}
构造函数
上面代码主要包含 BeanDefinitionLoader 实例的创建、设置一些属性、最后的装载。先让我看看 BeanDefinitionLoader 的构造函数。
java
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 = new XmlBeanDefinitionReader(registry);
this.groovyReader = (isGroovyPresent() ? new GroovyBeanDefinitionReader(registry) : null);
this.scanner = new ClassPathBeanDefinitionScanner(registry);
this.scanner.addExcludeFilter(new ClassExcludeFilter(sources));
}
从构造函数中可以看出,bean定义的加载主要有四种方式,分别为:注解的方式、xml配置方式、groovy脚本方式和路径扫描方式。在构造函数中提前构建好四种加载工具,在后续真正load()的地方再根据*sources* 的类型来判断具体使用哪种 reader 来完成bean定义的加载。
Spring boot 默认通过 AnnotatedBeanDefinitionReader 方式来加载bean定义。这里需要注意下在 AnnotatedBeanDefinitionReader 构造函数中会实例化 ConditionEvaluator 条件评估器,ConditionEvaluator 内部又会构造一个**ConditionContextImpl **实例。然后会将注解配置处理器注册到bean工厂中。
java
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
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, null);
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
让我们通过源码的方式详细分析下 registerAnnotationConfigProcessors 做了什么操作。
java
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry, @Nullable Object source) {
//从上下文中取出 beanFactory
DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
if (beanFactory != null) {
//注意这里设置dependencyComparator、autowireCandidateResolver 只有在首次实例化AnnotatedBeanDefinitionReader
//时才会赋值,而首次实例化是在'AnnotationConfigServletWebServerApplicationContext'上下文创建阶段。
if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
}
if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
}
}
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
//同理只在AnnotatedBeanDefinitionReader首次实例化时,才会注册以下相关后置处理器
if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// Check for Jakarta Annotations support, and if present add the CommonAnnotationBeanPostProcessor.
if ((jakartaAnnotationsPresent || jsr250Present) &&
!registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition();
try {
def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
AnnotationConfigUtils.class.getClassLoader()));
}
catch (ClassNotFoundException ex) {
throw new IllegalStateException(
"Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
}
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
}
return beanDefs;
}
注意 :在registerPostProcessor内部实际会调用DefaultListableBeanFactory. registerPostProcessor方法进行bean定义的注册,这里不详细介绍。大概的逻辑就是判断集合是否包含要注册的BeanDefinition,无就加入,存在就根据情况抛异常或者覆盖。具体逻辑可以阅读相关代码。
load() 加载
接下来让我们看看load()加载的具体实现。
java
void load() {
for (Object source : this.sources) {
load(source);
}
}
private void load(Object source) {
Assert.notNull(source, "Source must not be null");
if (source instanceof Class<?> clazz) {
load(clazz);
return;
}
if (source instanceof Resource resource) {
load(resource);
return;
}
if (source instanceof Package pack) {
load(pack);
return;
}
if (source instanceof CharSequence sequence) {
load(sequence);
return;
}
throw new IllegalArgumentException("Invalid source type " + source.getClass());
}
load的加载会判断 source 的类型,不同的类型走不同的处理逻辑。一般 source 是 Class类型,默认走以下方法进行处理。
java
private void 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);
((GroovyBeanDefinitionReader) this.groovyReader).beans(loader.getBeans());
}
if (isEligible(source)) {
this.annotatedReader.register(source);
}
}
可以看到,在 isEligible(source) == true 的情况,最终是通过 AnnotatedBeanDefinitionReader 来完成bean定义的注册。让我继续看看register(source )的实现。
java
private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
@Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
@Nullable BeanDefinitionCustomizer[] customizers) {
//创建AnnotatedGenericBeanDefinition实例对象,
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
//判断是否跳过bean的注册,根据条件判断(通常是被@Conditional注解)如果要跳过,则不进行bean定义的注册
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
return;
}
// 设置属性 org.springframework.context.annotation.ConfigurationClassPostProcessor.candidate = true
abd.setAttribute(ConfigurationClassUtils.CANDIDATE_ATTRIBUTE, Boolean.TRUE);
// 设置实例supplier
abd.setInstanceSupplier(supplier);
// 解析bean的作用域,并将作用域信息绑定到当前bean定义上
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
abd.setScope(scopeMetadata.getScopeName());
//生成bean名称
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
//处理通用定义注解,包含@Lazy、@Primary、@DependsOn、@Role、@Description,将其对应的值设置到AnnotatedGenericBeanDefinition中
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
if (qualifiers != null) {
for (Class<? extends Annotation> qualifier : qualifiers) {
if (Primary.class == qualifier) {
abd.setPrimary(true);
}
else if (Lazy.class == qualifier) {
abd.setLazyInit(true);
}
else {
abd.addQualifier(new AutowireCandidateQualifier(qualifier));
}
}
}
if (customizers != null) {
for (BeanDefinitionCustomizer customizer : customizers) {
customizer.customize(abd);
}
}
//构建bean定义holder对象
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
//根据bean定义的代理模式,确定是否生成一个代理的bean定义,决定后续生成bean的时候是否生成代理对象
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
//最后将bean定义注册到beanFactory中
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
经过以上的流程处理,我们最终识别出 sources 关联的注解并将他们解析成 BeanDefinition 注册到 beanFactory 中,为后续bean的实例化做准备。