深入浅出Spring注解ConfigurationProperties和EnableConfigurationProperties
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;
}
如何使用ConfigurationProperties
首先我们将注解加载配置类上
@ConfigurationProperties(prefix = ConfigurationProperties0.PREFIX)
public class ConfigurationProperties0 {
public static final String PREFIX = "qtfy";
}
编译报错提示需要以下方式进行扫描。
方法一:@Configuration(proxyBeanMethods = false)
在配置类上添加注解 @Configuration(proxyBeanMethods = false)
@ConfigurationProperties(prefix = ConfigurationProperties1.PREFIX)
@Configuration(proxyBeanMethods = false)
public class ConfigurationProperties1 {}
方法二: @Component
在配置类上添加注解 Component
@ConfigurationProperties(prefix = ConfigurationProperties2.PREFIX)
@Component
public class ConfigurationProperties2 {}
也可以添加其他三个标识组件注解。
方法三:EnableConfigurationProperties
@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(ConfigurationProperties3.class)
public class Config3 {
}
方法四:ConfigurationPropertiesScan
@Configuration(proxyBeanMethods = false)
@ConfigurationPropertiesScan(basePackageClasses = ConfigurationProperties4.class)
public class Config4 {
}
方法五: @Bean
@Configuration(proxyBeanMethods = false)
public class Config5 {
@Bean
public ConfigurationProperties5 properties5() {
return new ConfigurationProperties5();
}
}
方式六:@Import
@Configuration(proxyBeanMethods = false)
@Import(ConfigurationProperties6.class)
public class Config6 {
}
测试
@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
六种注册方式分析
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 {};
}
用法示例见方法三
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 {};
}
用法示例见方法四
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>
- 如果未添加依赖idea会提示,未配置Spring Boot配置注解处理器。
- 添加依赖后会提示,重新运行Spring Boot配置注解处理器以更新生成的元数据。
- 即使不添加依赖不会影响服务启动。
配置文件提示
我们在编写配置文件的时候经常会看到这样的提示
比如说这个配置
spring:
redis:
connect-timeout:
点进去找到 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;
效果
版权声明:本文为qq_37151886原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。