1. ClassPathBeanDefinitionScanner作用
扫描类路径下的类注册为bean定义。
2. 类声明
public class ClassPathBeanDefinitionScanner extends ClassPathScanningCandidateComponentProvider
/**
类名就是扫描类路径下bena定义。继承自类路径扫描候选组件提供器
类路径扫描候选组件提供器的作用:
扫描类路径下的时候,使用过滤器是否考虑作为候选者,作为待注入的bean定义。
**/
3. 属性
// beanDefinition注册器
private final BeanDefinitionRegistry registry;
// 存储默认的BeanDefinition属性值,如作用域(scope)、懒加载(lazy initialization)等设置。
private BeanDefinitionDefaults beanDefinitionDefaults = new BeanDefinitionDefaults();
// 定义了一组字符串模式,用于决定哪些被扫描到的类应该被认为是自动装配候选者(autowire
// candidates)。如果一个类的全限定名匹配这些模式之一,那么它将被视为可以进行自动装配的bean。
private String[] autowireCandidatePatterns;
// Bean名称生成器策略,默认是AnnotationBeanNameGenerator实例,它根据类上的注解或类名来生
// 成bean的名称.在扫描和注册bean的过程中,会用到这个策略来生成唯一的bean名称。
private BeanNameGenerator beanNameGenerator = AnnotationBeanNameGenerator.INSTANCE;
// 指定了作用域元数据解析器,默认使用AnnotationScopeMetadataResolver,它根据类上的注解
// (如@Component、@Service等)来确定bean的作用域(例如singleton或prototype)。
private ScopeMetadataResolver scopeMetadataResolver = new AnnotationScopeMetadataResolver();
// 如果为true,表示在扫描过程中不仅会处理带有特定注解(如@Component、@Repository、@Service、
// @Controller等)的类,还会处理类上的注解配置信息(如@Autowired、@Value等)。如果设置为
// false,则只扫描并注册类本身作为bean,而不处理注解驱动的配置。
private boolean includeAnnotationConfig = true;
4. 构造器
/*
单个参数的构造器: 传入注册器
*/
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry) {
// 调用本地构造器: 注册器,使用默认过滤器
this(registry, true);
}
/*
双参数的构造器: 传入注册器, 是否使用默认过滤器
*/
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters) {
// 调用本地构造器: 注册器, 是否使用默认的过滤器,获取或创建环境
this(registry, useDefaultFilters, getOrCreateEnvironment(registry));
}
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,
Environment environment) {
// 调用本地构造器:注册器,过滤器,环境,资源加载器(null)
this(registry, useDefaultFilters, environment,
(registry instanceof ResourceLoader ? (ResourceLoader) registry : 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);
}
5. 扫描方法
// 扫描指定包的类
public int scan(String... basePackages) {
// 获取当前注册器中bean定义的数量
int beanCountAtScanStart = this.registry.getBeanDefinitionCount();
// 去扫描指定的包
doScan(basePackages);
// Register annotation config processors, if necessary.
if (this.includeAnnotationConfig) {
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
// 返回注册后-之前已注册数量的差
return (this.registry.getBeanDefinitionCount() - beanCountAtScanStart);
}
6. 真正扫描方法
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) {
// 获取作用域
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
// 设置作用域
candidate.setScope(scopeMetadata.getScopeName());
// 按照beanName生成策略获取到bean名称
String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
// 如果是抽象BeanDefinition
if (candidate instanceof AbstractBeanDefinition) {
postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
}
// 如果是注解BeanDefinition
if (candidate instanceof AnnotatedBeanDefinition) {
AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
}
// 检查给定的候选BeanDefinition,确定相应的BeanDefinition是否需要注册或者是否和
// 已经存在的定义发生了冲突。
if (checkCandidate(beanName, candidate)) {
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
definitionHolder =
AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
beanDefinitions.add(definitionHolder);
registerBeanDefinition(definitionHolder, this.registry);
}
}
}
补充一下:
AbstractBeanDefinition、AnnotatedBeanDefinition都是spring框架中定义和处理BeanDefinition的类,他们在SpringIOC容器的核心机制中有重要的地位。文章来源地址https://www.toymoban.com/news/detail-795041.html
-
1. AbstractBeanDefinition:
- 是个抽象类,实现了 BeanDefinition 接口,为BeanDefinition提供了一些通用的方法和属性。
- 提供了BeanDefinition的基本结构,如作用域scope,初始化方法,销毁方法、依赖项管理等元数据信息的存储和操作
- 子类有:RootBeanDefinition、GenericBeanDefinition
-
2. AnnotatedBeanDefinition:
- 该类封装了一个被注解标注的类的信息,并能够从类上的注解提取Bean的元数据,如作用域、生命周期回调方法等。
- 在基于注解的配置环境下,Spring会使用 AnnotatedBeanDefinitionReader 或者 ClassPathBeanDefinitionScanner 等工具将带有注解的类转换为 AnnotatedBeanDefinition 对象并注册到IoC容器中。
7. postProcessBeanDefinition
protected void postProcessBeanDefinition(AbstractBeanDefinition beanDefinition, String beanName) {
beanDefinition.applyDefaults(this.beanDefinitionDefaults);
if (this.autowireCandidatePatterns != null) {
beanDefinition.setAutowireCandidate(PatternMatchUtils.
simpleMatch(this.autowireCandidatePatterns, beanName));
}
}
8. 注册bean定义
protected void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) {
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, registry);
}
文章来源:https://www.toymoban.com/news/detail-795041.html
到了这里,关于【Spring类路径Bean定义信息扫描】的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!