SpringBoot属性注入
首先准备好一个简单的SpringBoot项目,加入相关的依赖,这里就不做操作了
1、@Value 进行注入
application.properties 配置文件
strValue=这是字符串
intValue=1
doubleValue=10.2
person1.name=张三
city=广州,深圳,佛山
mapV={k1:'v1','k2':'v2'}
@Value的值有以下三大类:
①**@Value(“${ property : default_value}”)**
$注入的是外部配置文件对应的property,使用“ : ”对未配置或值为空的属性设置默认值。
②@Value(“#{ obj.property? :default_value}”)
#注入的是SpEL表达式对应的内容,使用“ ?: ”对未配置或值为空的表达式设置默认值。
③直接把值注入
@Value(“字符串类型的值”)
注意:在注入整型、Map时 需要使用 #{${}} 结合使用(可能在高版本的SpringBoot中有改变,我并不清楚这个)
测试类的代码:
package com.gx.democonfig.controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Arrays;
import java.util.Map;
@RestController
public class Test {
//通过配置属性注入
@Value("${strValue : 就算有值,还是默认值优先}")
private String str;
@Value("#{${intValue}}")
private int intValue;
@Value("#{${doubleValue}}")
private double doubleValue;
@Value("${person1.name}")
private String name;
@Value("${city}")
private String[] list;
@Value("#{${mapV}}")
Map<String, Object> mapList;
//直接注入
@Value("zhangsan")
private String userName;
@Value("123")
private int num;
//产生一个50~100之间的随机数
@Value("${random.int.50,100;}")
private int randomInt;
@RequestMapping("/test")
public String test() {
System.out.println("通过配置属性注入");
System.out.println("intValue = " + intValue);
System.out.println("doubleValue = " + doubleValue);
System.out.println("name = " + name);
System.out.println("list = " + Arrays.toString(list));
System.out.println("mapList = " + mapList);
System.out.println("str = " + str);
System.out.println();
System.out.println("直接注入");
System.out.println("userName = " + userName);
System.out.println("num = " + num);
System.out.println();
System.out.println("产生一个50~100之间的随机数");
System.out.println("randomInt = " + randomInt);
return "";
}
}
运行项目,打开浏览器输入 localhost:8080 (端口号默认是8080)刷新,然后在 Idae 的控制台查看输出信息
1、输出的值都是通过 application.properties 配置文件 得来的。
2、可以从 application.properties 配置文件 中看出,str 这个属性是给了值的,但是我再 @Value 中给了一个默认值,输出的就是默认值,由此可知是@Value的默认值优先。如果配置文件中没有该属性或者该属性没有赋值,那么输出的就是默认值。
3、@Value() 里面写的是什么,输出的就是什么。
4、@Value(“${random.int.50,100;}”) 这个随机数只有在注入的时候执行一次,无论你浏览器怎么刷新也不会有第二个随机数,你只能重新启动你的项目来刷新随机数。
@Value 在使用中也有诸多的不便,注入时需要一个一个的绑定,比较繁琐,适合少量注入。不支持复杂类型封装。
2、@ConfigurationProperties在实体类上注解注入属性值
application.properties 配置文件
person.name=张三app
person.age=23
person.sex=男
person.birth=2000/03/04
person.stage=true
person.lists=a,b,c,d,e,f,g
person.maps.name=jack
person.maps.age=12
person.child.name=路西
person.child.age=16
添加 lombok 的依赖
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
同时插件中也要排除一下
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
实体类代码 Person.java
package com.gx.democonfig.vo;
import lombok.Data;
import lombok.ToString;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import org.springframework.validation.annotation.Validated;
import javax.validation.constraints.Max;
import javax.validation.constraints.Size;
import java.util.Date;
import java.util.List;
import java.util.Map;
@Component
//声明当前类为属性读取类
//prefix:读取数据文件,前缀为person的值。在类上定义各个属性,名称必须与属性文件中person.的后面部分一致
@ConfigurationProperties(prefix = "person")
@Data //getter() 和 setter() 如果上面不添加 lombok 的依赖,这两个注解就无法注入
@ToString //ToString()方法
public class Person {
private String name;
private Integer age;
private String sex;
private Date birth;
private Boolean stage;
private List<Object> lists;
private Map<String,Object> maps;
private Child child;
}
使用@ConfigurationProperties后,IDEA会在编辑器顶部提示 Spring Boot Configuration Annotation Processor not configured :
可以添加配置文件处理器依赖,可以解决IDEA爆红,并且以后编写配置时就有提示了
<!--导入配置文件处理器,配置文件进行绑定就会有提示-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
测试类的代码
package com.gx.democonfig.controller;
import com.gx.democonfig.vo.Person;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class Test {
//通过构造器属性注入
private Person person;
@Autowired
public Test(Person person) {
this.person = person;
}
@RequestMapping("/test")
public String test() {
System.out.println(person);
//示例,获取某一个属性
System.out.println("name = " + person.getName());
return "";
}
}
刷新浏览器,在 Idae 的控制台查看输出信息
1、在Person类中加入@ConfigurationProperties(prefix = “person”),prefix或者value 是到 application.properties 配置文件中找到指定的前缀为 person 的数据
2、通过 @Data 或者 @Setter 将配置文件的数据注入,如果没有这两个的其中一个,输出的信息就位 null。@Data 里面就包含了 @Setter 和 @Getter 这两个注解。
3、手动添加 getter() / setter() 方法 与 注解@Data(@Getter/@Setter)的比较
这里使用 Person 类的 name 属性来测试,在Person类中添加下面的代码
public String getName() {
return name + " 手动添加 getter()";
}
public void setName(String name) {
this.name = name + " 手动添加 setter() ";
}
控制台查看输出信息
可以看出来,调用了手动添加的 getter() / setter() 方法
区别:
1、手动添加的优先级比极高,灵活性也比较高,可以在getter() / setter() 方法体中加入我们需要的东西,但是代码量比较大,idea也可以通过 alt + insert 一键生成。
2、@Data(@Getter/@Setter) 简化了代码的写入,代码看起来更简洁,如果单单只是需要 get/set ,推荐使用这个。