Spring Boot 之 BeanDefinitionLoader 详解

发布时间:2026/7/15 20:26:42
Spring Boot 之 BeanDefinitionLoader 详解 入口BeanDefinitionLoader顾名思义是用来加载bean定义的。在spring boot启动过程中的准备上下文件阶段会进行source关联资源的bean定义加载为后续bean的实例化做准备。关键代码如下//SpringApplication public class SpringApplication { //... private void prepareContext(...) { //... f (!AotDetector.useGeneratedArtifacts()) { // Load the sources SetObject 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的构造函数。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工厂中。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 做了什么操作。public static SetBeanDefinitionHolder 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()); } } SetBeanDefinitionHolder 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()加载的具体实现。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类型默认走以下方法进行处理。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)的实现。private T void doRegisterBean(ClassT beanClass, Nullable String name, Nullable Class? extends Annotation[] qualifiers, Nullable SupplierT 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的实例化做准备。注spring boot 版本为3.2.3