SpringBoot属性配置的多种方式
1.前言☕
大家好,我是Leo哥🫣🫣🫣,今天给大家带来关于精品SpringBoot专栏,暂且就给他起名为循序渐进学SpringBoot,这里我参考了我上一个专栏:循序渐进学SpringSecurity6。有需要的朋友可以抓紧学习来哈,带你从SpringSecurity从零到实战项目。好了,我们进入正题,为什么会有SpringBoot这个专栏呢,是这样的,今年Leo哥也是正在重塑知识体系,从基础到框架,而SpringBoot又是我们框架中的核心,我觉得很有必要通过以博客的形式将我的知识系列进行输出,同时也锻炼一下自己的写作能力,如果能帮到大家那就更好啦!!!本地系列教程会从SpringBoot基础讲起,会以知识点+实例+项目的学习模式由浅入深对Spring Boot框架进行学习&使用。好了,话不多说让我们开始吧😎😎😎。
2.@Value注解
@Value注解是Spring
框架提供的用于注入配置属性值的注解,它可用于类的成员变量
、方法参数
和构造函数
参数上,这个记住很重要!
在应用程序启动时,使用 @Value 注解的 Bean 会被实例化。所有使用了 @Value 注解的 Bean 会被加入到 PropertySourcesPlaceholderConfigurer
的后置处理器集合中。
当后置处理器开始执行时,它会读取 Bean 中所有 @Value 注解所标注的值,并通过反射将解析后的属性值赋值给标有 @Value 注解的成员变量、方法参数和构造函数参数。
2.1 基本用法
你可以使用@Value
来注入简单的字面量值:
yaml
val:
name: 程序员Leo
typescript
@Value("${val.name}")
private String name;
/**
* 用于测试:
*/
@Test
public void test01() {
System.out.println(name);
}
运气测试类即可拿到配置信息。
虽然@Value使用比较简单,但是这里有一个注意点,如果去读取配置文件没有的配置信息,则会报错。
为了避免此类错误导致服务启动异常,我们可以在引用变量的同时给它赋一个默认值,以确保即使在未正确配值的情况下,程序依然能够正常运行。
kotlin
@Value("${val.name:Leo}")
private String name;
同时@Value
注解也可以用来注入系统属性和环境变量:
kotlin
@Value("${JAVA_HOME}")
private String javaHome;
@Value("#{systemProperties['user.home']}")
private String userHome;
2.2 静态变量赋值
还有一种常见的使用误区,就是将 @Value 注解加到静态变量上,这样做是无法获取属性值的。静态变量是类的属性,并不属于对象的属性,而 Spring是基于对象的属性进行依赖注入的,类在应用启动时静态变量就被初始化,此时 Bean还未被实例化,因此不可能通过 @Value 注入属性值。
java
@Value("${val.age}")
private static int age;
可以看出来,直接赋值给静态变量是赋值不上去的。
即使 @Value 注解无法直接用在静态变量上,我们仍然可以通过获取已有 Bean实例化后的属性值,再将其赋值给静态变量来实现给静态变量赋值。
我们可以先通过 @Value 注解将属性值注入到普通 Bean中,然后在获取该 Bean对应的属性值,并将其赋值给静态变量。这样,就可以在静态变量中使用该属性值了。
注意事项:
- 确保你的类是由Spring管理的,即它应该是一个组件(@Component),配置(@Configuration),服务(@Service),存储库(@Repository)等,,由 Spring 管理的 bean 中使用 @Value注解才会生效。而对于普通的POJO类,则无法使用 @Value注解进行属性注入。
@Value
注解在某些情况下可能不是最佳选择,特别是当你有多个配置参数时。在这种情况下,使用@ConfigurationProperties
注解将属性绑定到一个配置类可能是更好的选择。@Value
不支持复杂类型的注入,比如列表和映射,而@ConfigurationProperties
可以很好地处理这些类型。
3.@ConfigurationProperties注解
前面我们学习了@Value注解,虽然很方便,但是对于我们多字段属性配置就会有点麻烦了。所以我们需要一个讲多个繁杂的属性配置文件直接映射到一个POJO对象上面去。
此时 @ConfigurationProperties 应运而生。它是 SpringBoot 提供的一种更加便捷来处理配置文件中的属性值的方式,可以通过自动绑定和类型转换等机制,将指定前缀的属性集合自动绑定到一个Bean对象上。
3.1 基本用法
下面演示使用 @ConfigurationProperties 注解,在 application.yml 配置文件中添加配置项:
yaml
bt:
v1: 公众号:程序员Leo
v2: 公众号:程序员Leo
创建一个 ConfProperties类用于承载所有前缀为bt
的配置属性。
less
@Data
@Configuration
@ConfigurationProperties(prefix = "bt")
public class ConfProperties {
private String v1;
private String v2;
}
在需要使用v1
、v2
属性值的地方,将 ConfProperties对象注入到依赖对象中即可。
java
@Resource
private ConfProperties confProperties;
结果如我们所预想:
3.2 嵌套属性
@ConfigurationProperties
还支持嵌套属性。如果你有嵌套的配置对象,你可以这样定义它们:
修改YML配置:
yaml
bt:
v1: 公众号:程序员Leo
v2: 公众号:程序员Leo
user:
name: 程序员Leo
age: 20
修改 ConfProperties 类
less
@Data
@Configuration
@ConfigurationProperties(prefix = "bt")
public class ConfProperties {
private String v1;
private String v2;
private User user;
}
可以看到,我们的嵌套user也已经进行了赋值。
4.Environment对象
对于Environment对象,如果大家经常看到Leo哥SpringBoot项目中的启动类,大家一定知道他。
那具体Environment对象具体如何使用呢,我们一步一步往下看。
4.1 什么是Environment
Environment
是一个由Spring Framework提供的接口,在Spring Boot中被广泛使用。它代表了当前应用程序运行时环境的抽象,并封装了与之相关的所有配置。通过 Environment
接口,你可以访问到properties文件、YAML文件、环境变量、命令行参数等多种来源的属性值。
4.2 如何使用
要使用 Environment
对象很简单,在需要使用它地方通过@Autowired注解即可将其注入
java
@Autowired
private Environment env;
可以看出来,依旧可以把我们的嵌套name打印出来。
我们在回过头来看我们的启动类代码,其实就不难理解了。
- 首先来看看 SpringApplication.run(ValidatorApplication.class, args) ,这是 Spring Boot 应用程序的标准启动方法。当你执行这个命令时,它会启动一个 Spring Boot 应用。
SpringApplication.run()
方法返回一个ConfigurableApplicationContext
对象,它表示 Spring 的应用上下文。 - Environment environment = context.getBean(Environment.class); 从
ConfigurableApplicationContext
中获取一个Environment
类型的 bean。Environment
是 Spring 框架中的一个接口,它表示应用程序的运行环境。你可以通过它来访问各种属性,如配置文件中的值。 - System.out.println("访问链接:http://localhost:" + environment.getProperty("server.port")); 这行代码从
Environment
中获取server.port
属性值,这通常是 Spring Boot 应用启动时的服务器端口。然后,它输出一个消息,告诉用户如何访问该应用。例如,如果server.port
的值为8080
,那么输出的链接将是http://localhost:8080
。
当我们SpringBoot启动之后,他大概呈现的就是这么一个效果:
利用 Environment
对象能够使得对复杂配置信息管理更加灵活方便,在处理多环境问题时尤其有优势。