当前位置: 首页 > news >正文

[注解: @ComponentScan]-原理分析

例子

@Configuration
public class CustomConfig {@Beanpublic Object customObj() {return new Object();}
}
public class CustomTypeFilter implements TypeFilter {@Overridepublic boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory)throws IOException {String className = metadataReader.getClassMetadata().getClassName();return className.contains("CustomConfig");}
}
@Configuration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = CustomTypeFilter.class), // 使用自定义过滤器@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class), @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) 
})
public class Application {@Beanpublic CommandLineRunner commandLineRunner(ApplicationContext ctx) {return args -> ctx.getBean(CustomConfig.class);}public static void main(String[] args) {SpringApplication.run(Application.class, args);}
}

源码

ComponentScan

配置包扫描逻辑,自动注册带注解的组件到 Spring 容器中。

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Repeatable(ComponentScans.class)
public @interface ComponentScan {@AliasFor("basePackages")String[] value() default {};@AliasFor("value")String[] basePackages() default {};Class<?>[] basePackageClasses() default {};Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;Class<? extends ScopeMetadataResolver> scopeResolver() default AnnotationScopeMetadataResolver.class;ScopedProxyMode scopedProxy() default ScopedProxyMode.DEFAULT;String resourcePattern() default ClassPathScanningCandidateComponentProvider.DEFAULT_RESOURCE_PATTERN;boolean useDefaultFilters() default true;Filter[] includeFilters() default {};Filter[] excludeFilters() default {};boolean lazyInit() default false;@Retention(RetentionPolicy.RUNTIME)@Target({})@interface Filter {FilterType type() default FilterType.ANNOTATION;@AliasFor("classes")Class<?>[] value() default {};@AliasFor("value")Class<?>[] classes() default {};String[] pattern() default {};}
}

追踪

1. SpringApplication

public class SpringApplication {private ApplicationContextFactory applicationContextFactory = ApplicationContextFactory.DEFAULT;public SpringApplication(Class<?>... primarySources) {this(null, primarySources);}protected ConfigurableApplicationContext createApplicationContext() {return this.applicationContextFactory.create(this.properties.getWebApplicationType());}// ...
}

2. ApplicationContextFactory

@FunctionalInterface
public interface ApplicationContextFactory {// ...ApplicationContextFactory DEFAULT = new DefaultApplicationContextFactory();
}
class DefaultApplicationContextFactory implements ApplicationContextFactory {@Overridepublic ConfigurableApplicationContext create(WebApplicationType webApplicationType) {try {return getFromSpringFactories(webApplicationType, ApplicationContextFactory::create,this::createDefaultApplicationContext);}catch (Exception ex) {throw new IllegalStateException("Unable create a default ApplicationContext instance, "+ "you may need a custom ApplicationContextFactory", ex);}}private ConfigurableApplicationContext createDefaultApplicationContext() {if (!AotDetector.useGeneratedArtifacts()) {return new AnnotationConfigApplicationContext();}return new GenericApplicationContext();}// ...
}

3. AnnotationConfigApplicationContext

public class AnnotationConfigApplicationContext extends GenericApplicationContext implements AnnotationConfigRegistry {private final AnnotatedBeanDefinitionReader reader;private final ClassPathBeanDefinitionScanner scanner;public AnnotationConfigApplicationContext() {StartupStep createAnnotatedBeanDefReader = getApplicationStartup().start("spring.context.annotated-bean-reader.create");this.reader = new AnnotatedBeanDefinitionReader(this);createAnnotatedBeanDefReader.end();this.scanner = new ClassPathBeanDefinitionScanner(this);}// ...
}

4. AnnotatedBeanDefinitionReader

public class AnnotatedBeanDefinitionReader {private final BeanDefinitionRegistry registry;private BeanNameGenerator beanNameGenerator = AnnotationBeanNameGenerator.INSTANCE;private ScopeMetadataResolver scopeMetadataResolver = new AnnotationScopeMetadataResolver();private ConditionEvaluator conditionEvaluator;public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {this(registry, getOrCreateEnvironment(registry));}public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {this.registry = registry;this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);// 注入注解相关的后置处理器,其中包含 ConfigurationClassPostProcessorAnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);}// ...
}

5. ConfigurationClassPostProcessor

具体分析可以参考一下这篇博客

public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor,BeanRegistrationAotProcessor, BeanFactoryInitializationAotProcessor, PriorityOrdered,ResourceLoaderAware, ApplicationStartupAware, BeanClassLoaderAware, EnvironmentAware {@Nullableprivate ConfigurationClassBeanDefinitionReader reader;@Overridepublic void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {int registryId = System.identityHashCode(registry);if (this.registriesPostProcessed.contains(registryId)) {throw new IllegalStateException("postProcessBeanDefinitionRegistry already called on this post-processor against " + registry);}if (this.factoriesPostProcessed.contains(registryId)) {throw new IllegalStateException("postProcessBeanFactory already called on this post-processor against " + registry);}this.registriesPostProcessed.add(registryId);processConfigBeanDefinitions(registry);}public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {List<BeanDefinitionHolder> configCandidates = new ArrayList<>();String[] candidateNames = registry.getBeanDefinitionNames();for (String beanName : candidateNames) {BeanDefinition beanDef = registry.getBeanDefinition(beanName);if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) != null) {if (logger.isDebugEnabled()) {logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);}}else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));}}// Return immediately if no @Configuration classes were foundif (configCandidates.isEmpty()) {return;}// Sort by previously determined @Order value, if applicableconfigCandidates.sort((bd1, bd2) -> {int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());return Integer.compare(i1, i2);});// Detect any custom bean name generation strategy supplied through the enclosing application contextSingletonBeanRegistry singletonRegistry = null;if (registry instanceof SingletonBeanRegistry sbr) {singletonRegistry = sbr;if (!this.localBeanNameGeneratorSet) {BeanNameGenerator generator = (BeanNameGenerator) singletonRegistry.getSingleton(AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR);if (generator != null) {this.componentScanBeanNameGenerator = generator;this.importBeanNameGenerator = generator;}}}if (this.environment == null) {this.environment = new StandardEnvironment();}// Parse each @Configuration class// 创建 PropertySourceRegistry, ComponentScanAnnotationParser 处理 @ConfigurationClassParser parser = new ConfigurationClassParser(this.metadataReaderFactory, this.problemReporter, this.environment,this.resourceLoader, this.componentScanBeanNameGenerator, registry);Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);Set<ConfigurationClass> alreadyParsed = CollectionUtils.newHashSet(configCandidates.size());do {StartupStep processConfig = this.applicationStartup.start("spring.context.config-classes.parse");parser.parse(candidates);parser.validate();Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());configClasses.removeAll(alreadyParsed);// Read the model and create bean definitions based on its contentif (this.reader == null) {this.reader = new ConfigurationClassBeanDefinitionReader(registry, this.sourceExtractor, this.resourceLoader, this.environment,this.importBeanNameGenerator, parser.getImportRegistry());}this.reader.loadBeanDefinitions(configClasses);alreadyParsed.addAll(configClasses);processConfig.tag("classCount", () -> String.valueOf(configClasses.size())).end();candidates.clear();if (registry.getBeanDefinitionCount() > candidateNames.length) {String[] newCandidateNames = registry.getBeanDefinitionNames();Set<String> oldCandidateNames = Set.of(candidateNames);Set<String> alreadyParsedClasses = CollectionUtils.newHashSet(alreadyParsed.size());for (ConfigurationClass configurationClass : alreadyParsed) {alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());}for (String candidateName : newCandidateNames) {if (!oldCandidateNames.contains(candidateName)) {BeanDefinition bd = registry.getBeanDefinition(candidateName);if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) &&!alreadyParsedClasses.contains(bd.getBeanClassName())) {candidates.add(new BeanDefinitionHolder(bd, candidateName));}}}candidateNames = newCandidateNames;}}while (!candidates.isEmpty());// Register the ImportRegistry as a bean in order to support ImportAware @Configuration classesif (singletonRegistry != null && !singletonRegistry.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {singletonRegistry.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());}this.propertySourceDescriptors = parser.getPropertySourceDescriptors();if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory cachingMetadataReaderFactory) {cachingMetadataReaderFactory.clearCache();}}@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {int factoryId = System.identityHashCode(beanFactory);if (this.factoriesPostProcessed.contains(factoryId)) {throw new IllegalStateException("postProcessBeanFactory already called on this post-processor against " + beanFactory);}this.factoriesPostProcessed.add(factoryId);if (!this.registriesPostProcessed.contains(factoryId)) {processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory);}enhanceConfigurationClasses(beanFactory);beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));}// ...}
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;@Overridedefault void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {}}

6. ConfigurationClassParser

class ConfigurationClassParser {// ConfigurationClassPostProcessor.processConfigBeanDefinitionspublic ConfigurationClassParser(MetadataReaderFactory metadataReaderFactory,ProblemReporter problemReporter, Environment environment, ResourceLoader resourceLoader,BeanNameGenerator componentScanBeanNameGenerator, BeanDefinitionRegistry registry) {// CachingMetadataReaderFactorythis.metadataReaderFactory = metadataReaderFactory;// FailFastProblemReporterthis.problemReporter = problemReporter;this.environment = environment;this.resourceLoader = resourceLoader;// @PropertySourcethis.propertySourceRegistry = (this.environment instanceof ConfigurableEnvironment ce ?new PropertySourceRegistry(new PropertySourceProcessor(ce, this.resourceLoader)) : null);this.registry = registry;//  @ComponentScanthis.componentScanParser = new ComponentScanAnnotationParser(environment, resourceLoader, componentScanBeanNameGenerator, registry);this.conditionEvaluator = new ConditionEvaluator(registry, environment, resourceLoader);}public void parse(Set<BeanDefinitionHolder> configCandidates) {for (BeanDefinitionHolder holder : configCandidates) {BeanDefinition bd = holder.getBeanDefinition();try {ConfigurationClass configClass;if (bd instanceof AnnotatedBeanDefinition annotatedBeanDef) {configClass = parse(annotatedBeanDef, holder.getBeanName());}else if (bd instanceof AbstractBeanDefinition abstractBeanDef && abstractBeanDef.hasBeanClass()) {configClass = parse(abstractBeanDef.getBeanClass(), holder.getBeanName());}else {configClass = parse(bd.getBeanClassName(), holder.getBeanName());}// Downgrade to lite (no enhancement) in case of no instance-level @Bean methods.if (!configClass.getMetadata().isAbstract() && !configClass.hasNonStaticBeanMethods() &&ConfigurationClassUtils.CONFIGURATION_CLASS_FULL.equals(bd.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE))) {bd.setAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE,ConfigurationClassUtils.CONFIGURATION_CLASS_LITE);}}catch (BeanDefinitionStoreException ex) {throw ex;}catch (Throwable ex) {throw new BeanDefinitionStoreException("Failed to parse configuration class [" + bd.getBeanClassName() + "]", ex);}}// 加载 DeferredImportSelector// 此时 AutoConfigurationImportSelector.selectImports() 被触发this.deferredImportSelectorHandler.process();}private ConfigurationClass parse(AnnotatedBeanDefinition beanDef, String beanName) {ConfigurationClass configClass = new ConfigurationClass(beanDef.getMetadata(), beanName, (beanDef instanceof ScannedGenericBeanDefinition));processConfigurationClass(configClass, DEFAULT_EXCLUSION_FILTER);return configClass;}private ConfigurationClass parse(Class<?> clazz, String beanName) {ConfigurationClass configClass = new ConfigurationClass(clazz, beanName);processConfigurationClass(configClass, DEFAULT_EXCLUSION_FILTER);return configClass;}final ConfigurationClass parse(@Nullable String className, String beanName) throws IOException {Assert.notNull(className, "No bean class name for configuration class bean definition");MetadataReader reader = this.metadataReaderFactory.getMetadataReader(className);ConfigurationClass configClass = new ConfigurationClass(reader, beanName);processConfigurationClass(configClass, DEFAULT_EXCLUSION_FILTER);return configClass;}protected void processConfigurationClass(ConfigurationClass configClass, Predicate<String> filter) {if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) {return;}ConfigurationClass existingClass = this.configurationClasses.get(configClass);if (existingClass != null) {if (configClass.isImported()) {if (existingClass.isImported()) {existingClass.mergeImportedBy(configClass);}// Otherwise ignore new imported config class; existing non-imported class overrides it.return;}else if (configClass.isScanned()) {String beanName = configClass.getBeanName();if (StringUtils.hasLength(beanName) && this.registry.containsBeanDefinition(beanName)) {this.registry.removeBeanDefinition(beanName);}// An implicitly scanned bean definition should not override an explicit import.return;}else {// Explicit bean definition found, probably replacing an import.// Let's remove the old one and go with the new one.this.configurationClasses.remove(configClass);removeKnownSuperclass(configClass.getMetadata().getClassName(), false);}}// Recursively process the configuration class and its superclass hierarchy.SourceClass sourceClass = null;try {sourceClass = asSourceClass(configClass, filter);do {sourceClass = doProcessConfigurationClass(configClass, sourceClass, filter);}while (sourceClass != null);}catch (IOException ex) {throw new BeanDefinitionStoreException("I/O failure while processing configuration class [" + sourceClass + "]", ex);}this.configurationClasses.put(configClass, configClass);}@Nullableprotected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass, Predicate<String> filter)throws IOException {if (configClass.getMetadata().isAnnotated(Component.class.getName())) {// Recursively process any member (nested) classes firstprocessMemberClasses(configClass, sourceClass, filter);}// Process any @PropertySource annotationsfor (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(sourceClass.getMetadata(), org.springframework.context.annotation.PropertySource.class,PropertySources.class, true)) {if (this.propertySourceRegistry != null) {this.propertySourceRegistry.processPropertySource(propertySource);}else {logger.info("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() +"]. Reason: Environment must implement ConfigurableEnvironment");}}// Search for locally declared @ComponentScan annotations first.Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(sourceClass.getMetadata(), ComponentScan.class, ComponentScans.class,MergedAnnotation::isDirectlyPresent);// Fall back to searching for @ComponentScan meta-annotations (which indirectly// includes locally declared composed annotations).if (componentScans.isEmpty()) {componentScans = AnnotationConfigUtils.attributesForRepeatable(sourceClass.getMetadata(),ComponentScan.class, ComponentScans.class, MergedAnnotation::isMetaPresent);}if (!componentScans.isEmpty()) {List<Condition> registerBeanConditions = collectRegisterBeanConditions(configClass);if (!registerBeanConditions.isEmpty()) {throw new ApplicationContextException("Component scan for configuration class [%s] could not be used with conditions in REGISTER_BEAN phase: %s".formatted(configClass.getMetadata().getClassName(), registerBeanConditions));}for (AnnotationAttributes componentScan : componentScans) {// The config class is annotated with @ComponentScan -> perform the scan immediatelySet<BeanDefinitionHolder> scannedBeanDefinitions =this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());// Check the set of scanned definitions for any further config classes and parse recursively if neededfor (BeanDefinitionHolder holder : scannedBeanDefinitions) {BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();if (bdCand == null) {bdCand = holder.getBeanDefinition();}// 对于 @ComponentScan 扫描到的每个 Bean,如果它本身也是一个“配置类候选者”,// 则再次调用 parse() 递归处理它的配置信息(如 @Bean、@Import、@ComponentScan 等)if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {parse(bdCand.getBeanClassName(), holder.getBeanName());}}}}// Process any @Import annotationsprocessImports(configClass, sourceClass, getImports(sourceClass), filter, true);// Process any @ImportResource annotationsAnnotationAttributes importResource =AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);if (importResource != null) {String[] resources = importResource.getStringArray("locations");Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");for (String resource : resources) {String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);configClass.addImportedResource(resolvedResource, readerClass);}}// Process individual @Bean methodsSet<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);for (MethodMetadata methodMetadata : beanMethods) {if (methodMetadata.isAnnotated("kotlin.jvm.JvmStatic") && !methodMetadata.isStatic()) {continue;}configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));}// Process default methods on interfacesprocessInterfaces(configClass, sourceClass);// Process superclass, if anyif (sourceClass.getMetadata().hasSuperClass()) {String superclass = sourceClass.getMetadata().getSuperClassName();if (superclass != null && !superclass.startsWith("java")) {boolean superclassKnown = this.knownSuperclasses.containsKey(superclass);this.knownSuperclasses.add(superclass, configClass);if (!superclassKnown) {// Superclass found, return its annotation metadata and recursereturn sourceClass.getSuperClass();}}}// No superclass -> processing is completereturn null;}// ...
}

7. ComponentScanAnnotationParser

class ComponentScanAnnotationParser {private final Environment environment;private final ResourceLoader resourceLoader;private final BeanNameGenerator beanNameGenerator;private final BeanDefinitionRegistry registry;public ComponentScanAnnotationParser(Environment environment, ResourceLoader resourceLoader, BeanNameGenerator beanNameGenerator, BeanDefinitionRegistry registry) {this.environment = environment;this.resourceLoader = resourceLoader;this.beanNameGenerator = beanNameGenerator;this.registry = registry;}public Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan, String declaringClass) {ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(this.registry,componentScan.getBoolean("useDefaultFilters"), this.environment, this.resourceLoader);Class<? extends BeanNameGenerator> generatorClass = componentScan.getClass("nameGenerator");boolean useInheritedGenerator = (BeanNameGenerator.class == generatorClass);scanner.setBeanNameGenerator(useInheritedGenerator ? this.beanNameGenerator :BeanUtils.instantiateClass(generatorClass));ScopedProxyMode scopedProxyMode = componentScan.getEnum("scopedProxy");if (scopedProxyMode != ScopedProxyMode.DEFAULT) {scanner.setScopedProxyMode(scopedProxyMode);}else {Class<? extends ScopeMetadataResolver> resolverClass = componentScan.getClass("scopeResolver");scanner.setScopeMetadataResolver(BeanUtils.instantiateClass(resolverClass));}scanner.setResourcePattern(componentScan.getString("resourcePattern"));for (AnnotationAttributes includeFilterAttributes : componentScan.getAnnotationArray("includeFilters")) {List<TypeFilter> typeFilters = TypeFilterUtils.createTypeFiltersFor(includeFilterAttributes, this.environment,this.resourceLoader, this.registry);for (TypeFilter typeFilter : typeFilters) {scanner.addIncludeFilter(typeFilter);}}for (AnnotationAttributes excludeFilterAttributes : componentScan.getAnnotationArray("excludeFilters")) {List<TypeFilter> typeFilters = TypeFilterUtils.createTypeFiltersFor(excludeFilterAttributes, this.environment,this.resourceLoader, this.registry);for (TypeFilter typeFilter : typeFilters) {scanner.addExcludeFilter(typeFilter);}}boolean lazyInit = componentScan.getBoolean("lazyInit");if (lazyInit) {scanner.getBeanDefinitionDefaults().setLazyInit(true);}Set<String> basePackages = new LinkedHashSet<>();String[] basePackagesArray = componentScan.getStringArray("basePackages");for (String pkg : basePackagesArray) {String[] tokenized = StringUtils.tokenizeToStringArray(this.environment.resolvePlaceholders(pkg),ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);Collections.addAll(basePackages, tokenized);}for (Class<?> clazz : componentScan.getClassArray("basePackageClasses")) {basePackages.add(ClassUtils.getPackageName(clazz));}if (basePackages.isEmpty()) {basePackages.add(ClassUtils.getPackageName(declaringClass));}scanner.addExcludeFilter(new AbstractTypeHierarchyTraversingFilter(false, false) {@Overrideprotected boolean matchClassName(String className) {return declaringClass.equals(className);}});return scanner.doScan(StringUtils.toStringArray(basePackages));}}

8. ClassPathBeanDefinitionScanner

public class ClassPathBeanDefinitionScanner extends ClassPathScanningCandidateComponentProvider {public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters, Environment environment) {this(registry, useDefaultFilters, environment,(registry instanceof ResourceLoader resourceLoader ? resourceLoader : null));}public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters, Environment environment, @Nullable ResourceLoader resourceLoader) {Assert.notNull(registry, "BeanDefinitionRegistry must not be null");this.registry = registry;if (useDefaultFilters) {registerDefaultFilters();}setEnvironment(environment);setResourceLoader(resourceLoader);}// 真正完成扫描包、解析组件、注册 BeanDefinition 的核心所在protected Set<BeanDefinitionHolder> doScan(String... basePackages) {Assert.notEmpty(basePackages, "At least one base package must be specified");Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();for (String basePackage : basePackages) {Set<BeanDefinition> candidates = findCandidateComponents(basePackage);for (BeanDefinition candidate : candidates) {// @ScopeScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);candidate.setScope(scopeMetadata.getScopeName());String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);// 后处理 BeanDefinitionif (candidate instanceof AbstractBeanDefinition abstractBeanDefinition) {postProcessBeanDefinition(abstractBeanDefinition, beanName);}//  处理通用注解(@Lazy、@Primary、@DependsOn)if (candidate instanceof AnnotatedBeanDefinition annotatedBeanDefinition) {AnnotationConfigUtils.processCommonDefinitionAnnotations(annotatedBeanDefinition);}// 检查是否重复命名冲突if (checkCandidate(beanName, candidate)) {BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);beanDefinitions.add(definitionHolder);// 创建并注册 BeanDefinitionHolderregisterBeanDefinition(definitionHolder, this.registry);}}}return beanDefinitions;}
}
http://www.dtcms.com/a/273118.html

相关文章:

  • Cloudflare 发布容器服务公测版:边缘计算新时代来临?
  • 职坐标:嵌入式AI边缘计算实战
  • React 实现五子棋人机对战小游戏
  • FFmpeg Windows安装
  • 定位模拟的详细步骤
  • vue3使用mermaid生成图表,并可编辑
  • 数学建模:多目标规划:ε约束法、 理想点法
  • 【大模型推理论文阅读】Enhancing Latent Computation in Transformerswith Latent Tokens
  • pharokka phold--快速噬菌体注释工具
  • 深入了解 Vim 编辑器:从入门到精通
  • MySQL高级特性全面解析:约束、表关系、多表查询与事务
  • 深入剖析C++ RPC框架原理:有栈协程与分布式系统设计
  • 技术学习_检索增强生成(RAG)
  • QT数据交互全解析:JSON处理与HTTP通信
  • 云原生技术与应用-Docker高级管理--Dockerfile镜像制作
  • 西部数据WD授权代理商-深圳同袍存储科技有限公司
  • 医学+AI!湖北中医药大学信息工程学院与和鲸科技签约101数智领航计划
  • Web后端开发工程师AI协作指南
  • 龙迅#LT7911E适用于TPYE-C/DP/EDP转MIPIDSI/LVDS应用功能,支持DSC 分辨率缩放,分辨率高达4K60HZ!
  • 寒武纪MLU370编程陷阱:float32精度丢失的硬件级解决方案——混合精度训练中的定点数补偿算法设计
  • Linux指令与权限
  • uniapp滚动组件, HuimayunScroll:高性能移动端滚动组件的设计与实现
  • window显示驱动开发—XR_BIAS 和 PresentDXGI
  • Spring原理揭秘--ApplicationContext(二)
  • bRPC源码解析:深入理解bthread协程机制与上下文切换的底层实现
  • 单相/三相可选:光伏并网双向计量电表技术白皮书
  • 【研报复现】方正金工:(1)适度冒险 因子
  • 【网络】Linux 内核优化实战 - net.ipv4.tcp_keepalive_intv
  • Linux 命令行与 shell 脚本编程大全4版学习-1了解Linux
  • tk.mybatis多层括号嵌套SQL查询