一分钟深挖@Value注解和@ConfigurationProperities注解的区别
目录
一、 注解来源
二、@Value注解
1. @Value注解定义:
2. 使用步骤:
3.代码示例
三、Environment对象
1. Environment对象的定义:
2.代码示例
四、@ConfigurationProperities注解
1.@ConfigurationProperities注解的定义
2.@ConfigurationProperities注解使用方法
3.代码示例
五、@Value注解和@ConfigurationProperities注解的对比分析
1.底层框架
2.功能
3.为属性设置setter方法
4.复杂类型属性注入
5.松散绑定
6.JSR303数据校验
7.SpEL表达式
六、总结
一、 注解来源
使用Spring boot全局配置文件配置属性的时候,如果配置的是spring boot内置的属性,那么Springboot会自动扫描并读取配置文件中的属性值并覆盖原有默认的属性。如果配置的文件是用户自定义的属性,可以通过java代码去读取该配置属性,并且把属性绑定到bean。在Springboot项目中可以通过@Value、Enviroment对象和@ConfigurationProperities注解对配置文件进行绑定。
二、@Value注解
1. @Value注解定义:
@Value
注解是Spring框架提供的一个用于属性注入的注解,它能够将配置文件中的属性值绑定到Spring管理的Bean对象的属性上。这使得开发者可以很方便地将配置信息(如数据库连接信息、应用设置等)从配置文件中读取并注入到应用程序的组件中。
2. 使用步骤:
1)创建实体类并在属性上使用@Value注解注入配置文件中的属性
首先,定义一个Java类,并在类的属性上使用@Value
注解来指定要注入的配置项。@Value
注解的value属性用于指定配置文件中属性的键名。
2)在项目的resource文件夹下创建配置文件application.yml中添加属性信息
在Spring Boot项目中,通常会在src/main/resources
目录下创建一个名为application.yml
或application.properties
的配置文件,并在其中定义配置项。
3)在测试类中注入对象,并新增方法输出测试
通过Spring的依赖注入机制,将使用@Value
注解的Bean注入到其他需要使用这些配置信息的组件中,并编写测试代码来验证注入是否成功。
3.代码示例
1)创建实体类并使用@Value注解
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class MyConfigProperties {
// 使用@Value注解指定要从配置文件中注入的属性值
@Value("${app.name}")
private String appName;// 用于存储应用名称的私有属性
@Value("${app.version}")
private String appVersion;// 用于存储应用版本的私有属性
// Getters and Setters
public String getAppName() {
return appName;
}
public void setAppName(String appName) {
this.appName = appName;
}
public String getAppVersion() {
return appVersion;
}
public void setAppVersion(String appVersion) {
this.appVersion = appVersion;
}
}
2)在application.yml文件中添加属性信息
app:
name: MyApplication
version: 1.0.0
3)在测试类或Springboot的启动类中注入对象并测试
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MyApplication implements CommandLineRunner {
@Autowired
private MyConfigProperties myConfigProperties;
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
System.out.println("Application Name: " + myConfigProperties.getAppName());
System.out.println("Application Version: " + myConfigProperties.getAppVersion());
}
}
4)运行结果:
当运行上述Springboot应用时,控制台将输出:
Application Name: MyApplication
Application Version: 1.0.0
这表明MyConfigProperties
类中的appName
和appVersion
属性已成功从application.yml
配置文件中注入。
三、Environment对象
1. Environment对象的定义:
使用@Value注解的时候,将该注解标注在Spring管控的Bean的属性名上方,就可以将某个数据绑定到Bean对象的属性。当Bean的属性比较多且这些属性都需要绑定配置的数据时,操作起来就比较繁琐。为此,Springboot提供了一个对象Environment,项目在启动时能够将配置文件中所有数据都封装到该对象中,这样就不需要手动对配置数据进行绑定。而且,Environment对象在获取配置文件中的数据时,不需要再提供其他实体类。
2.代码示例
在@Value的代码示例的测试类或Springboot的启动类代码中,通过@Autowired注入Environment对象,并新增测试方法evnTest(),在测试方式桶通过Environment对象获取配置文件中的属性,具体代码如下:
@Autowired
private Environment env;
@Test
void evnTest(){
System.out.println("myConfigProperties.name=" + env.getProperty("myConfigProperties.name"));
System.out.println("myConfigProperties.version=" + env.getProperty("myConfigProperties.version"));
}
上述代码的evnTest(),方法中,使用Environment对象的getProperty()方法获取封装到Environment对象中的配置文件的数据,该方法的参数为配置数据键的名称。
运行测试方法evnTest(),控制台会输出以下内容:
myConfigProperties.name=MyApplication
myConfigProperties.version=1.0.0
四、@ConfigurationProperities注解
1.@ConfigurationProperities注解的定义
Java是面向对象的语言,很多情况下,人们习惯将具有相同特性的一组数据封装到一个对象中,Springboot中就提供了这样的注解。Springboot的@ConfigurationProperities注解允许我们将配置文件中的属性绑定到一个Java对象中。
这个注解通常用于将application.properties
或application.yml
等配置文件中的一组相关属性封装到一个POJO(Plain Old Java Object)中。简单来说就是可以可以将配置文件中的一组数据同时绑定到Bean中。在项目中使用@ConfigurationProperities注解绑定全局配置文件中的数据。
2.@ConfigurationProperities注解使用方法
1) 创建一个配置类:这个类通常是一个普通的Java类,它包含了与配置文件中的属性相对应的字段。字段的类型应该与配置文件中的属性值类型相匹配。
2) 在配置类上使用@ConfigurationProperties
注解:指定配置文件中的前缀(prefix),这样Spring Boot就知道要将哪些属性绑定到这个类的字段上。
3) 确保配置类被Spring管理:这通常通过@Component
注解或通过将其作为一个Bean定义在配置类中来实现。
4) 在application.properties
或application.yml
中定义属性:确保这些属性的键名与配置类中的字段名(考虑到前缀)相匹配。
5) 使用配置类:一旦配置类被创建并绑定到配置文件中的属性,你就可以在应用程序的任何地方注入这个配置类,并使用它的字段来访问配置属性。
3.代码示例
1)创建配置类:
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties(prefix = "myapp")
public class MyAppProperties {
private String name;
private int version;
// getters and setters
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getVersion() {
return version;
}
public void setVersion(int version) {
this.version = version;
}
}
2)在application.properties中定义属性
myapp.name=My Application
myapp.version=1.0.0
3)使用配置类
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MyApplication implements CommandLineRunner {
@Autowired
private MyAppProperties myAppProperties;
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
System.out.println("Application Name: " + myAppProperties.getName());
System.out.println("Application Version: " + myAppProperties.getVersion());
}
}
4)结果输出:
Application Name: My Application
Application Version: 1.0.0
在这个示例中,我们创建了一个名为MyAppProperties
的配置类,并使用@ConfigurationProperties(prefix = "myapp")
注解将其与配置文件中以myapp
为前缀的属性绑定。然后,在application.properties
文件中定义了myapp.name
和myapp.version
属性。最后,在MyApplication
类中注入了MyAppProperties
对象,并在应用程序启动时打印了这些属性的值。
五、@Value注解和@ConfigurationProperities注解的对比分析
通过前面的内容可知,@Value注解和@ConfigurationProperities注解都可以对配置文件中的属性进行绑定,但两者在使用过程中还是有一些差异的。软件开发人员进行技术选型时,应秉承高度的责任感,以问题为导向,根据实际应用场景选择更适合的技术,并制定合理的解决方案,在复杂的业务环境下科学的做好技术选型。
下面我们来进一步了解两者的不同:
对比项 | @Value | @ConfigurationProperities |
底层框架 | Spring | Spring Boot |
功能 | 单个注入配置文件的属性 | 批量注入配置文件的属性 |
为属性设置setter方法 | 不需要 | 需要 |
复杂类型属性注入 | 不支持 | 支持 |
松散绑定 | 不支持 | 支持 |
JSR303数据校验 | 不支持 | 支持 |
SpEL表达式 | 支持 | 不支持 |
1.底层框架
@Value注解是由Spring框架提供的,只不过Springboot框架对Spring进行了默认支持,所以也可以使用@Value注解的相关功能;@ConfigurationProperities注解是由Springboot框架提供的。
2.功能
@Value注解只需要注入属性值的单个属性上进行注入配置;@ConfigurationProperities注解主要用于将配置文件中的某一类整体批量读取并注入到Bean的属性中。
3.为属性设置setter方法
@Value不需要为属性设置setter方法,该注解会先通过表达式读取配置文件中指定的属性值,然后自动注入到下方的Bean属性上。如果读取的配置文件属性值为空,进行属性注入时程序会报错。
@ConfigurationProperities注解进行配置文件属性注入的时候,还必须为每一个属性设置setter方法。如果配置文件中没有配置属性值,则会自动将对应的Bean属性设置为空。
4.复杂类型属性注入
@Value在注入复杂数据类型配置数据时,会无法解析,导致注入失败;
@ConfigurationProperities注解支持任意数据类型的属性注入。
5.松散绑定
@ConfigurationProperities注解进行配置文件属性注入时,支持松散绑定语法。例如Person类中有一个字符串类型的firstName,可以绑定配置文件中的以下属性:
person.firstName = james //标准写法,对应Person类属性名
person.first-name = james //使用横线-分隔多个单词
person.first_name = james //使用下划线_分隔多个单词
PERSON.FIRST_NAME = james //使用大小写格式,推荐常量属性配置
上述示例中列举了@ConfigurationProperities注解进行配置文件属性值注入时,支持的配置文件语法,属于松散绑定语法,而@Value注解不支持此功能。
6.JSR303数据校验
JSR303数据校验的主要作用是校验配置文件中注入到Bean属性的值是否符合相关值的规则,@ConfigurationProperities注解进行配置文件属性注入时,支持JSR303数据校验,示例代码如下:
@Component
@ConfigurationProperities(prefix = "person")
@Validated //引入Spring框架支持的数据校验规则
public class Example{
@Email //对属性进行规则匹配
private String email;
public void setEmail(String email){
this.email = email;
}
}
在上述代码中,使用@ConfigurationProperities注解注入配置文件属性值时,在实体类Example上引用@Validated注解用于数据校验,在属性email上引入@Email注解进行对应会泽校验。如果注入的配置文件属性值不符合相关校验规则,程序会自动报错。@Value注解不支持JSR303数据校验功能。
7.SpEL表达式
使用@Value注解注入配置文件属性时,支持SpEL表达式语法,即 “ #{xx} ” 。例如Person类中有一个整数类型id,可直接使用SpEL表达式进行属性注入,代码示例如下:
@Value("#{5*2}") //使用@Value注解的SpEL表达式直接为属性注入值
private in id;
在上述代码中,列举了在不使用配置文件的情况下,可以直接使用@Value注解支持的SpEL表达式进行Bean的属性值注入,而@ConfigurationProperities注解不支持此功能。
六、总结
上述对于@Value注解和@ConfigurationProperities注解进行配置文件属性注入的主要区别进行了对比分析,但两者并没有明显的优劣之分,它们只是适合的应用场景不同而已,不同场景下的使用推荐如下:
如果只是针对某一个业务需求,要引入配置文件中的个别属性,推荐使用@Value注解。
如果针对某个Java Bean类,需要批量注入属性值,则推荐使用@ConfigurationProperities注解。
如果文章对您有帮助,还请您点赞支持
感谢您的阅读,欢迎您在评论区留言指正分享