前言
接下来讲讲为什么写这边文章以及为什么需要这两个注解以及这两个注解的区别以及使用的不同场景:
-
为什么写这篇文章?
这两个在所有的视频教程中都是必讲,但是大多数视频都是讲了怎么用,在教学视频中大多数都是千篇一律的讲用人啊宠物啊怎么注入进去这些举例,而忽略了实际开发中的需求,为什么用?在哪用?同时这个两个注解初学者常常会混淆以及理解不清!! -
首先讲讲为什么会需要使用这两个注解?
这两个注解的作用都是给程序动态赋配置文件中的值,使用配置文件的方式结合注解注入非常灵活,而且更便于管理和维护。 -
区别
下面正文说明!
为什么需要使用这两个注解
以前开发的程序都是使用xml,xml的好处是什么呢?易维护,对于运维人员来说是好的,但是对于开发者来说随着网站的规模变大以及功能的增多,光是xml的配置就让人很头大,spring也不断的在简化一块,这不spring boot就是这一块的代表作。spring boot 默认使用Java配置类来配置程序的相关框架配置。
- 而Java配置类最典型的表型就是其是代码级别的,对开发人员来说友好,自己使用的编程语言还是相对熟悉的,不再需要关注xml,但是有一个很不友好的就是改配置,要改代码,需要重新编译,对运维人员来说还需要懂得各种语言的代码配置类,这不是增大压力吗?而且一个大型程序重启的很耗时间的。
- 有时候只是需要修改一些配置属性,所以这两个注解其实是spring用来解决配置硬编码问题解决方案。
区别
功能性使用
@ConfigurationProperties | @value | |
---|---|---|
功能 | 批量注入配置文件中的属性 | 一个个指定 |
松散绑定(松散语法) | 支持 | 不支持 |
SpEL | 不支持 | 支持 |
JSR303数据校验 | 支持 | 不支持 |
复杂类型封装 | 支持 | 不支持 |
注解作用访问
@ConfigurationProperties作用于类
@Value作用于属性
松散绑定
所谓松散语法也就是属性命名规则(Relaxed binding)
- person.firstName:使用标准方式
- person.first-name:大写用-
- person.first_name:大写用_
- PERSON_FIRST_NAME: 系统属性推荐使用这种写法
@ConfigurationProperties支持松散语法
@Value不支持松散语法
注意:application.properties文件中有字段 persion.first-name
@Component
@ConfigurationProperties(prefix = "person")
public class Person {
private String firstName;
}
注意使用@ConfigurationProperties的前提,必须是spring 的组件
,即需要同时配置组件相关注解配合才能使用如
:@Component
或是 @Configuration
等
JSR303数据校验(@Validation)
@ConfigurationProperties @Validated 支持 @Value不支持
复制代码
import javax.validation.constraints.NotNull;
import org.hibernate.validator.constraints.Email;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.validation.annotation.Validated;
@ConfigurationProperties
@Validated
public class Properties {
@NotNull
private String userName;
@Email
private String email;
}
SpEl
@ConfigurationProperties不支持EL表达式
application.properties文件中有字段 person.userAge=12
userAge = 12 //可以
userAge = #{2*6} //EL表达式不支持
我们可以通过配置yml或者是properties文件赋予相关属性默认值。如一些系统相关的参数
,举个例子比如配置cookie,session,一些过期时间,资源路径啊
什么的这些场景都是非常适合的,而且方便管理。而且还可以结合spring配置给不同的环境来配置不同的值
,非常实用。
引用别处的案例:(当然赋值也不限于使用配置文件的值)
在配置类中使用@PropertySource注解读取外部的资源配置文件:
使用@Value注入表达式:
1.注入普通字符
@Value("注入普通字符")
2.注入操作系统属性
@Value(#{SystemProperties['os.name']})
3.表达式
@Value(#T(java.lang.Math).random()*100.0)
4.其他Bean的属性
@Value("#{其他Bean的name.其他Bean的属性}")
5. 文件资源
@Value("classpath:其他文件的路径")
6.网址资源
@Value("www.baidu.com")
7.其他配置文件的属性,注意这个使用$,而不是#
@Value("${book.name}")
package config;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.*;
import org.springframework.core.env.Environment;
import org.springframework.core.io.Resource;
import repository.dao.UserDAO;
import service.DemoService;
import service.FunctionService;
import service.UseFunctionService;
import java.io.IOException;
@Configuration
@ComponentScan(basePackages = "main.java.com.example.demo")
@PropertySource(value={"test.properties"})
public class SpringConfig {
@Bean // 通过该注解来表明是一个Bean对象,相当于xml中的<bean>
public DemoService demoService(){
return new DemoService(); // 直接new对象做演示
}
@Value("注入普通字符串")// 注入普通字符串
private String normal;
@Value("#{systemProperties['os.name']}")// 注入操作系统属性
private String osName;
@Value("#{T(java.lang.Math).random() * 100.0 }")// 注入表达式结果
private double randomNumber;
@Value("#{demoService.another}")// 注入其他Bean属性
private String fromAnother;
@Value("classpath:test.txt")// 注入文件资源
private Resource testFile;
@Value("https://www.baidu.com")// 注入网址资源
private Resource testUrl;
@Value("${book.name}")// 注入配置文件【注意是$符号】
private String bookName;
@Autowired// Properties可以从Environment获得
private Environment environment;//属性文件
@Override
public String toString() {
try {
return "ELConfig [normal=" + normal
+ ", osName=" + osName
+ ", randomNumber=" + randomNumber
+ ", fromAnother=" + fromAnother
+ ", testFile=" + IOUtils.toString(testFile.getInputStream())
+ ", testUrl=" + IOUtils.toString(testUrl.getInputStream())
+ ", bookName=" + bookName
+ ", environment=" + environment.getProperty("book.name") + "]";
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
}
使用二者的原则
使用原则:在某个业务逻辑
中需要获取一下配置文件中的某项值,使用@Value
;如果专门编写了一个javaBean来和配置文件
进行映射,我们就直接使用@ConfigurationProperties
,像是自定义starter这样的场景@ConfigurationProperties还是非常重要的;
案例出处说明:
参考博客:https://www.cnblogs.com/cyxdn/p/7999549.html