【源码】Spring —— AnnotatedBeanDefinitionReader 解读

【源码】Spring —— AnnotatedBeanDefinitionReader 解读

前言

我们最熟悉的 Spring 容器 AnnotationConfigApplicationContext,其内部有两个成员属性 AnnotatedBeanDefinitionReaderClassPathBeanDefinitionScanner 用于解析并注册对应的 BeanDefinition 对象到容器中

本章节,了解一下 AnnotatedBeanDefinitionReader

关于 BeanDefinition,可阅读下面的文章

【源码】Spring —— BeanDefinition 解读1

【源码】Spring —— BeanDefinition 解读2

版本

Spring 5.2.x

AnnotatedBeanDefinitionReader

当我们以如下代码

AnnotationConfigApplicationContext ac =
				new AnnotationConfigApplicationContext(MyConfig.class);

初始化一个容器时,解析组件类 MyConfig 中对应的 BeanDefinition

属性

	private final BeanDefinitionRegistry registry;

	/**
	 * public static final AnnotationBeanNameGenerator INSTANCE 
	 * 			= new AnnotationBeanNameGenerator();
	 */
	private BeanNameGenerator beanNameGenerator = AnnotationBeanNameGenerator.INSTANCE;

	private ScopeMetadataResolver scopeMetadataResolver = new AnnotationScopeMetadataResolver();

	private ConditionEvaluator conditionEvaluator;
  • BeanDefinitionRegistry,注册中心,此处就是容器本身

  • AnnotationBeanNameGenerator,用于给被标注了 @Component 以及被标注 @Component 注解的其他注解(比如 @Service 等)所标注的 bean,以及被其他规范下如 @ManagedBean @Named 等注解标注的 bean 生成对应的 beanName,如果无法从注解的属性中解析,则根据一定规则处理类名生成,比如 ExampleClass -> exampleClass

  • AnnotationScopeMetadataResolver,用于解析对应的 ScopeMetadata

  • ConditionEvaluator,用于解析 Condition 相关注解,判断是否注册目标 BeanDefinition。详细了解可查看下面文章

【源码】Spring —— Condition 条件匹配解读

构造

	// 初始化 registry conditionEvaluator 
	public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {

		this.registry = registry;
		this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);

		AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
	}

在初始化时,AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry) 方法会帮我们注册以下 BeanDefinition

  • ConfigurationClassPostProcessor,不存在对应 BeanDefinition 则注册,支持 @Configuration 注解的解析
  • AutowiredAnnotationBeanPostProcessor,不存在对应 BeanDefinition 则注册,支持 @Autowired @Value 等注解的解析
  • CommonAnnotationBeanPostProcessor,引入 了JSR-250 相关依赖且不存在对应 BeanDefinition 则注册,支持 @Resource 等注解的解析
  • PersistenceAnnotationBeanPostProcessor,引入了 JPA 相关依赖且不存在对应 BeanDefinition 则注册,支持 JPA 相关后处理
  • EventListenerMethodProcessor,不存在对应 BeanDefinition 则注册,负责对 @EventListener 注解标注的方法进行后处理
  • DefaultEventListenerFactory,不存在对应 BeanDefinition 则注册,主要由 EventListenerMethodProcessor 使用,用来基于 @EventListener 注解标注的方法获取对应 ApplicationListener

BeanDefinition 的注册(register)

	// 也允许多个配置类~
	public void register(Class<?>... componentClasses) {
		for (Class<?> componentClass : componentClasses) {
			registerBean(componentClass);
		}
	}

	public void registerBean(Class<?> beanClass) {
		doRegisterBean(beanClass, null, null, null, null);
	}

	<T> void doRegisterBean(Class<T> beanClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name,
			@Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {

		AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);

		// Condition 检验
		if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
			return;
		}

		abd.setInstanceSupplier(instanceSupplier);

		// ScopeMetadata 解析
		ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
		abd.setScope(scopeMetadata.getScopeName());
		
		// beanName 解析
		String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));

		// 基于 元数据 解析 Lazy Primary DependsOn Role Description 属性
		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));
				}
			}
		}

		// BeanDefinitionCustomizer 自定义回调
		for (BeanDefinitionCustomizer customizer : definitionCustomizers) {
			customizer.customize(abd);
		}

		BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);

		// 代理处理
		definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
		
		// 注册最终的 BeanDefinition	
		BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
	}

流程总结:

  • 构造的是 AnnotatedGenericBeanDefinition,因为是直接基于配置类扫描
  • Condition 相关校验
  • ScopeMetadata 解析
  • 基于 元数据 解析 Lazy Primary DependsOn Role Description 属性
  • qualifiers 参数相关
  • 可以传入 BeanDefinitionCustomizer 来自定义目标 BeanDefinition
  • 封装目标 BeanDefinition 并调用 AnnotationConfigUtils.applyScopedProxyMode 方法,逻辑简述:根据之前解析的 ScopeMetadata 判断是否需要代理,如果需要代理,则会值得目标类型为 ScopedProxyFactoryBean:这主要是针对作用域实例需要代理的场景
  • 注册目标 BeanDefinition

总结

基于配置类扫描 BeanDefinition 的常用类,跟 ClassPathBeanDefinitionScanner 是一个级别的存在

关于 ClassPathBeanDefinitionScanner,可阅读下面的文章

【源码】Spring —— ClassPathBeanDefinitionScanner 解读

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值