配置文件
1. application.yml
# 字面量(数字,字符串,布尔) server: port: 8081 user: user-name: 张三 age: 26 mobile: 18369615874 hobby: [吃饭,睡觉,打豆豆] map: {k1: 吃饭,k2: 睡觉} pwd: 123456
2. test.properties
user.user-name=李四 user.pwd=1234567896 user.mobile=1889394848223 user.age=289 user.hobby=吃饭,睡觉,打豆豆 user.map.k1=123456 user.map..k2=456789
导入jar包依赖
<!‐‐导入配置文件处理器,配置文件进行绑定就会有提示,配合热启动更好用‐‐> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring‐boot‐configuration‐processor</artifactId> <optional>true</optional> </dependency> <!--热启动--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> </dependency>
一、@ConfigurationProperties注解
1、@ConfigurationProperties作用
- 告诉SpringBoot将本类中的所有属性和配置文件中相关的配置进行绑定;*prefix="user":配置文件中user下面的所有属性和javaBena进行一一映射
- 只有这个组件是容器中的组件,才能容器提供的@ConfigurationProperties功能,下面的注解都是一样
- @ConfigurationProperties默认从全局配置文件中获取值;
2、@ConfigurationProperties用法
import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; import java.util.Map; @Data @Component @ConfigurationProperties(prefix = "user") public class User { private String userName; private String mobile; private String pwd; private int age; private String[] hobby; private Map<String,String> map; }
二、@Value注解
1、@Value的作用
将配制文件中的某个属性和bean中的值进行绑定注入,也可以使用SPeL给bean属性赋值
2、@Value的使用方法
2.1. 将bean中属性和主配置文件中的内容进行绑定和注入,不支持复杂类型的封装,如果有复杂类型就会原样输出,如果是多对键值对的map会直接报错
@Data @Component //@ConfigurationProperties(prefix = "user") @Validated public class User { @Value("${user.user-name}") private String userName; @Value("${user.mobile}") private String mobile; @Value("${user.pwd}") private String pwd; @Value("${user.age}") private int age; @Value("${user.hobby}") private String[] hobby; //@Value("${user.map}") private Map<String,String> map; } //打印结果 2019-07-04 10:16:30.211 INFO 29088 --- [ main] com.example.demo.DemoApplicationTests : Started DemoApplicationTests in 3.013 seconds (JVM running for 3.856) User(userName=张三, mobile=18369615874, pwd=123456, age=26, hobby=[${user.hobby}], map=null) ${user.hobby} 2019-07-04 10:16:30.405 INFO 29088 --- [ Thread-3] o.s.s.concurrent.ThreadPoolTaskExecutor : Shutting down ExecutorService 'applicationTaskExecutor'
2.2. 直接给bean注入字面量属性,数组只能注入一个值,不支持map和对象
@Data @Component //@ConfigurationProperties(prefix = "user") @Validated public class User { @Value("李四") private String userName; @Value("18697563215") private String mobile; @Value("123456") private String pwd; @Value("25") private int age; @Value("吃饭") private String[] hobby; //@Value("k1:12456") private Map<String,String> map; }
2.3. 使用SpEL表达式实现注入
@Data @Component //@ConfigurationProperties(prefix = "user") @Validated public class User { //1、SpEL字面量(数字,字符串(字符串要带单引号),布尔值) @Value("#{'张三'}") private String userName; @Value("#{'18396547866'}") private String mobile; //2、调用java方法 @Value("#{new String(new java.util.Random().nextInt(10000000))}") private String pwd; @Value("#{new java.util.Random().nextInt(110)}") private int age; //3、数组 @Value("#{{'吃饭','睡觉','打豆豆'}}") private String[] hobby; //4、map和object @Value("#{{'k1':'victory','k2':'haha'}}") private Map<String,String> map; } //结果打印 2019-07-04 11:18:11.290 INFO 8856 --- [ main] com.example.demo.DemoApplicationTests : Started DemoApplicationTests in 4.371 seconds (JVM running for 5.547) User(userName=张三, mobile=18396547866, pwd=1561715, age=45, hobby=[吃饭, 睡觉, 打豆豆], map={k1=victory, k2=haha}) 吃饭 睡觉 打豆豆 2019-07-04 11:18:11.571 INFO 8856 --- [ Thread-3] o.s.s.concurrent.ThreadPoolTaskExecutor : Shutting down ExecutorService 'applicationTaskExecutor'
三、@Value和@ConfigurationProperties的区别
注解 | @Value | @ConfigurationPropertie |
功能 | 批量注入配置文件中的属性 | 一个个指定 |
松散绑定(松散语法) | 支持 | 不支持 |
SpEL | 不支持 | 支持 |
JSR303数据校验 | 支持 | 不支持 |
复杂类型封装 | 支持 | 不支持 |
名词解释:
- 松散绑定(松散语法):以userName为例,松散绑定是指userName、user-name和user_name是等价的,可是识别
- Spel:Spring表达式
- JSR303参数校验:是指在注入之前进行参数的格式校验
- 复杂类型的封装:支持数组、map和对象
四、@PropertySource注解
1. @PropertySource作用
- 通知spring容器加载指定的一个或多个配置文件
- 主配置文件和指定配置文件都有相应的配置属性以主配置文件的属性内容为准
- 多个配置文件中都存在同一属性以第一个配置文件为准
- 多个配置文件才凑成整个bean的属性时,配置内容互补
- 只能读取.properties文件
2. @PropertySource使用方法
- 配合@ConfigurationProperties使用
import lombok.Data; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.PropertySource; import org.springframework.stereotype.Component; import org.springframework.validation.annotation.Validated; import java.util.Map; import java.util.Random; @Data @Component @PropertySource(value = {"classpath:test.properties"}) @ConfigurationProperties(prefix = "user") public class User { private String userName; private String mobile; private String pwd; private int age; private String[] hobby; private Map<String,String> map; } //打印结果 2019-07-04 15:50:52.969 INFO 36388 --- [ main] com.example.demo.DemoApplicationTests : Started DemoApplicationTests in 4.356 seconds (JVM running for 5.111) User(userName=张三, mobile=188939484826, pwd=123456789, age=28, hobby=[吃饭, 睡觉, 打豆豆], map={k1=123456, k2=456789}) 吃饭 睡觉 打豆豆
- 配合@Value使用
@Data @Component @PropertySource(value = {"classpath:test.properties","classpath:test1.properties"}) //@ConfigurationProperties(prefix = "user") public class User { @Value("${user.user-name}") private String userName; @Value("${user.mobile}") private String mobile; @Value("${user.pwd}") private String pwd; @Value("${user.age}") private int age; private String[] hobby; private Map<String,String> map; } //打印结果 2019-07-04 15:54:56.870 INFO 35940 --- [ main] com.example.demo.DemoApplicationTests : Started DemoApplicationTests in 4.548 seconds (JVM running for 5.963) User(userName=张三, mobile=188939484826, pwd=123456789, age=28, hobby=null, map=null)
五、@ImportResource注解和@Bean
1. @ImportResource的作用
- 导入Spring的配置文件,让配置文件里面的内容生效;
- SpringBoot里面没有Spring的配置文件,我们自己编写的配置文件,也不能自动识别;想让Spring的配置文件生效,加载进来;
- @ImportResource标注在一个配置类上
2. @ImportResource的使用方法
- 添加配制文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="helloService" class="com.example.demo.service.HelloService"></bean> </beans>
- 在启动类上添加@ImportResource注解
@ImportResource(value = {"classpath:bean.xml"}) @SpringBootApplication public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } } //service类 package com.example.demo.service; public class HelloService { public void say(){ System.out.println("我是helloService"); } }
- 测试
@RunWith(SpringRunner.class) @SpringBootTest public class DemoApplicationTests { @Autowired User user; @Autowired HelloService helloService; @Test public void contextLoads() { helloService.say(); } } //打印结果 2019-07-04 16:30:24.621 INFO 36608 --- [ main] com.example.demo.DemoApplicationTests : Started DemoApplicationTests in 3.795 seconds (JVM running for 4.732) 我是helloService
3. 注意,虽然springboot支持这种写法,但建议使用@Bean注解的方式来替代spring的配置
- 写一个配置类
package com.example.demo.config; import com.example.demo.service.HelloService; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class MyHelloServiceConfig { @Bean //将方法的返回值添加到容器中;容器中这个组件默认的id就是方法名 public HelloService helloService(){ System.out.println("@Bean给spring中添加组件了"); return new HelloService(); }
- 测试代码同上
//2019-07-04 16:37:42.161 INFO 27808 --- [ main] com.example.demo.DemoApplicationTests : Started DemoApplicationTests in 3.476 seconds (JVM running for 4.402) 我是helloService