Spring配置属性管理(一)— @Value注解解析

本文介绍了Spring中如何使用@Value注解管理配置属性,详细解析了AutowiredAnnotationBeanPostProcessor如何处理BeanDefinition和PropertyValues。通过分析postProcessMergedBeanDefinition和postProcessProperties方法,展示了注入元数据InjectionMetadata的构建和注入过程。文章还探讨了PropertySourcesPropertyResolver在属性解析中的作用,以及Spring Boot中的PropertySourcesPlaceholderConfigurer如何增强属性源。
摘要由CSDN通过智能技术生成

为了能够更好的说明nacos-spring-project的设计原理,我们将首先介绍一下在Spring框架中是如何管理系统属性以及用户的配置属性的。本文将从一个项目中常用的属性使用例子入手,简要的分析属性解析注入的过程,在后续的文章中将从Environment的角度分析Spring是如何进行全局的属性管理的。

@Value注解

@Service
public class Test {
   

    @Value("${test}")
    private String test;

}

在项目中,如上面的代码片段所示,我们通常会在Service Bean中利用@Value注解来注入配置文件(例如application.properties)中的某些自定义配置属性,这些属性实际上都是由Spring Environment负责进行统一管理与解析的,而由AutowiredAnnotationBeanPostProcessor负责在Bean中对@Value注解进行解析注入属性的。

AutowiredAnnotationBeanPostProcessor实现了SmartInstantiationAwareBeanPostProcessor以及MergedBeanDefinitionPostProcessor接口,在程序初始化时主要完成了两件事:

  • 在postProcessMergedBeanDefinition接口中解析每个Bean的BeanDefinition,查找Bean中所有被定义的@Value以及@Autowired(本文不作细致分析),并解析成InjectionMetadata

  • 在postProcessProperties接口中找到Bean以及对应属性的InjectionMetadata,由InjectionMetadata来负责对PropertyValues进行注入

postProcessMergedBeanDefinition

在postProcessMergedBeanDefinition中最重要的任务就是从BeanDefinition中构造出InjectionMetadata,InjectionMetadata顾名思义即表示了每个Bean注入的元信息。AutowiredAnnotationBeanPostProcessor中的injectionMetadataCache缓存了所有Bean的InjectionMetadata,而InjectionMetadata中每个需要被注入的点都用一个InjectedElement来表示。

InjectionMetadata的解析主要是通过buildAutowiringMetadata函数利用反射来对Bean Class中的Field以及Method进行解析,要被注入的属性被封装成AutowiredFieldElement,要被注入的方法(方法参数上带有注解)被封装成AutowiredMethodElement。

private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
   
   if (!AnnotationUtils.isCandidateClass(clazz, this.autowiredAnnotationTypes)) {
   
      return InjectionMetadata.EMPTY;
   }

   List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
   Class<?> targetClass = clazz;

   do {
   
      final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();

      ReflectionUtils.doWithLocalFields(targetClass, field -> {
   
         //获取Field上的@Value或@Autowired注解
         MergedAnnotation<?> ann = findAutowiredAnnotation(field);
         if (ann != null) {
   
            //忽略静态属性
            if (Modifier.isStatic
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值