• 深入浅出Spring注解ConfigurationProperties


    ConfigurationProperties

    源码

    //修饰类型和方法
    @Target({ ElementType.TYPE, ElementType.METHOD })
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface ConfigurationProperties {
    	//value和prefix互为别名
    	@AliasFor("prefix")
    	String value() default "";
    	//value和prefix互为别名
    	@AliasFor("value")
    	String prefix() default "";
    	//忽略无效字段,默认不生效
    	boolean ignoreInvalidFields() default false;
    	//忽略不知道的字段,默认生效
    	boolean ignoreUnknownFields() default true;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    如何使用ConfigurationProperties

    首先我们将注解加载配置类上

    @ConfigurationProperties(prefix = ConfigurationProperties0.PREFIX)
    public class ConfigurationProperties0 {
        public static final String PREFIX = "qtfy";
    }
    
    • 1
    • 2
    • 3
    • 4

    编译报错提示需要以下方式进行扫描。
    在这里插入图片描述

    方法一:@Configuration(proxyBeanMethods = false)

    在配置类上添加注解 @Configuration(proxyBeanMethods = false)

    @ConfigurationProperties(prefix = ConfigurationProperties1.PREFIX)
    @Configuration(proxyBeanMethods = false)
    public class ConfigurationProperties1 {}
    
    • 1
    • 2
    • 3

    方法二: @Component

    在配置类上添加注解 Component

    @ConfigurationProperties(prefix = ConfigurationProperties2.PREFIX)
    @Component
    public class ConfigurationProperties2 {}
    
    • 1
    • 2
    • 3

    也可以添加其他三个标识组件注解。
    在这里插入图片描述

    方法三:EnableConfigurationProperties

    @Configuration(proxyBeanMethods = false)
    @EnableConfigurationProperties(ConfigurationProperties3.class)
    public class Config3 {
    }
    
    • 1
    • 2
    • 3
    • 4

    方法四:ConfigurationPropertiesScan

    @Configuration(proxyBeanMethods = false)
    @ConfigurationPropertiesScan(basePackageClasses = ConfigurationProperties4.class)
    public class Config4 {
    }
    
    • 1
    • 2
    • 3
    • 4

    方法五: @Bean

    @Configuration(proxyBeanMethods = false)
    public class Config5 {
    
        @Bean
        public ConfigurationProperties5 properties5() {
            return new ConfigurationProperties5();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    方式六:@Import

    @Configuration(proxyBeanMethods = false)
    @Import(ConfigurationProperties6.class)
    public class Config6 {
    }
    
    • 1
    • 2
    • 3
    • 4

    测试

    @SpringBootTest
    class PropertiesApplicationTests {
    
        @Autowired
        ConfigurationProperties2 c2;
    
        @Autowired
        ConfigurationProperties1 c1;
    
        @Autowired
        ConfigurationProperties3 c3;
    
        @Autowired
        ConfigurationProperties4 c4;
    
        @Autowired
        ConfigurationProperties5 c5;
        
        @Autowired
        ConfigurationProperties6 c6;
    
    
        @Test
        void contextLoads() {
            System.out.println(poolSize);
            System.out.println(c1.getAge());
            System.out.println(c2.getAge());
            System.out.println(c3.getAge());
            System.out.println(c4.getAge());
            System.out.println(c5.getAge());
           	System.out.println(c6.getAge());
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    输出

    1
    2
    3
    4
    5
    6
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    六种注册方式分析

    1和2最大的问题就是需要修改Properties类。3和4的区别在于一个是指定具体的class数组,一个是扫描包下所有的类,粒度不同,更推荐EnableConfigurationProperties的形式。

    在这里插入图片描述
    看一下实现就知道绝大多数都是使用这种方式来配置的。5和6属于可以用但是不推荐的选择。

    EnableConfigurationProperties

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Import(EnableConfigurationPropertiesRegistrar.class)
    public @interface EnableConfigurationProperties {
    
    	String VALIDATOR_BEAN_NAME = "configurationPropertiesValidator";
    
    	Class<?>[] value() default {};
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    用法示例见方法三

    ConfigurationPropertiesScan

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Import(ConfigurationPropertiesScanRegistrar.class)
    @EnableConfigurationProperties
    public @interface ConfigurationPropertiesScan {
    	//value和basePackages互为别名
    	@AliasFor("basePackages")
    	String[] value() default {};
    	//value和basePackages互为别名
    	@AliasFor("value")
    	String[] basePackages() default {};
    	//给定class作为扫描包
    	Class<?>[] basePackageClasses() default {};
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    用法示例见方法四

    Configuration Metadata 配置元数据

    Generating Your Own Metadata by Using the Annotation Processor

    Configuring the Annotation Processor 配置

    添加依赖

            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-configuration-processor</artifactId>
                <optional>true</optional>
            </dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    1. 如果未添加依赖idea会提示,未配置Spring Boot配置注解处理器。
    2. 添加依赖后会提示,重新运行Spring Boot配置注解处理器以更新生成的元数据。
    3. 即使不添加依赖不会影响服务启动。

    配置文件提示

    我们在编写配置文件的时候经常会看到这样的提示
    有些时候
    比如说这个配置

    spring:
      redis:
        connect-timeout:
    
    • 1
    • 2
    • 3

    点进去找到 RedisProperties 这么一个配置类。可以定位到 org.springframework.boot.autoconfigure.data.redis这么一个包,包有一个目录是META-INF,里面有一个spring-configuration-metadata.json文件,里面定义了配置文件中见到的key

    在这里插入图片描述
    如何实现呢?

    第一步添加spring-boot-configuration-processor这个依赖,第二步执行编译命令complie。执行后查看target目录没有添加依赖后编译结果如下
    在这里插入图片描述
    添加依赖后编译结果
    在这里插入图片描述
    回到配置文件测试已经具有了提示功能。
    在这里插入图片描述

    添加注释和默认值

        /**
         * 姓名
         */
        private String name;
    
        /**
         * 年龄
         */
        private int age;
        
            /**
         * 默认年龄
         */
        private int ageDefault = 18;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    效果
    在这里插入图片描述

  • 相关阅读:
    FB显示学习期数据不足怎么办?
    Go-Excelize API源码阅读(十)—— SetActiveSheet(index int)
    干货| 算法工程师常见问题(基础算法篇)
    前端---CSS的盒模型
    组合索引实例
    Bootstrap实例累积
    微信小程序开发入门与实战(数据监听)
    微软推出的Microsoft Fabric 到底是什么?
    Java中的队列Queue
    令人头秃,Java到底该怎么学啊?!零基础的可以自学吗?这份“限量版”Java零基础宝典让你不再烦恼,学习也能如此轻松!
  • 原文地址:https://blog.csdn.net/qq_37151886/article/details/127664874