赞
踩
目录
@ConfigurationProperties与@Value两种注解对比
SpringBoot使用一个以application命名的配置文件作为默认的全局配置文件。支持properties后缀结尾的配置文件或者以yml/yaml后缀结尾的YAML的文件配置。
以设置应用端口为例:
properties文件示例(application.properties):
server.port=80
YAML文件示例(application.yml):
server: port: 80
假如各配置文件都配置了不同的端口,那么SpringBoot会使用哪一个端口呢?带着疑问试验一下实例
4.结论:可见在同一目录下,properties配置优先级 > YAML配置优先级。//所以我们在jar包启动时带上properties写法的配置可以覆盖配置
SpringBoot配置文件可以放置在多种路径下,不同路径下的配置优先级有所不同。
可放置目录(优先级从高到低)
- file:./config/ (当前项目路径config目录下);
- file:./ (当前项目路径下);
- classpath:/config/ (类路径config目录下);
- classpath:/ (类路径config下).
优先级由高到底,高优先级的配置会覆盖低优先级的配置;
SpringBoot会从这四个位置全部加载配置文件并互补配置;
我们可以从ConfigFileApplicationListener这类便可看出,其中DEFAULT_SEARCH_LOCATIONS属性设置了加载的目录:
private static final String DEFAULT_SEARCH_LOCATIONS = "classpath:/,classpath:/config/,file:./,file:./config/";
接着getSearchLocations方法中去逗号解析成Set,其中内部类Loader负责这一配置文件的加载过程,包括加载profile指定环境的配置,以application+’-’+name格式的拼接加载。
多种目录配置同时存在情况
接下来还是以端口配置为例
- 在项目路径config目录下配置文件设置端口为7777;
- 在项目路径下配置文件设置端口为6666;
- 在resources/config目录下配置文件设置端口为9999;
- 在resources/目录下配置文件设置端口为8888;
最终运行结果:
Tomcat started on port(s): 7777 (http) with context path '/beedo' Started BeedoApplication in 4.544 seconds (JVM running for 5.335)
通过控制变量法得以论证
其优先级由高到底,高优先级的配置会覆盖低优先级的配置
SpringBoot提供了许多的配置,但通常情况我们需要自定义自己的配置应用自己的系统中,如你需要配置一个默认的用户名密码做为系统的登录用。
首先创建一个实体类,作为配置注入用,并使用**@ConfigurationProperties注解进行批量注入, 也可以使用Spring底层注解
@Value("${user.username}")**的方式一个一个注入达到同意的效果
- @Component
- @ConfigurationProperties(prefix = "user")
- public class Login{
- private String username;
- private String password;
- ...
- }
或者@Value写法
- @Component
- public class Login{
-
- private String username;
- private String password;
- ...
- }
配置yaml文件
user: username: admin password: 123
或者properties文件
login.username=admin login.password=123
编写一个junit测试用例,看看配置的值是否正常注入:
- @RunWith(SpringRunner.class)
- @SpringBootTest
- public class DeployApplicationTests {
- @Autowired
- private Login login;
- @Test
- public void contextLoads() {
- System.out.println(login);
- }
- }
从输出结果上看,值已正常注入
Login{username=‘admin’, password=‘123’}
比较项 | @ConfigurationProperties | @Value |
---|---|---|
全量注入 | 支持 | 否 |
松散绑定(Relaxed binding) | 支持 | 否 |
SpEL | 否 | 支持 |
JSR303 | 支持 | 不支持 |
**松散绑定:**驼峰命名(userName)、横干拼接(user-name)、下划线(user_name)之间可以互相识别绑定称为做松散绑定 **JSR303:**通过@Email,@Nullable,@Digits 等等注解进行邮箱、判空、数字格式等等数据的校验,更多相关内容请参考IBM的中文文档:https://www.ibm.com/developerworks/cn/java/j-lo-jsr303/index.html @ConfigurationProperties通常用于将配置全量注入某个类中; @Value通常用于注入某一些特定配置值中;
在编写配置时,你会发现自定义配置没有提示,让你在使用自定义配置时变的很麻烦,其实SpringBoot早已为我们准备好了提示的需要,只需要用引入相关依赖即可有提示。
在没有加入依赖时idea会有如下提示:
添加依赖,该idea提示便消失,编写自定义配置时也有相应提示:
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-configuration-processor</artifactId>
- <optional>true</optional>
- </dependency>
需要运行一下
通常情况下我们将配置配置在application开头的主配置文件中,这样随着项目的增大配置项的增多会使文件变得非常臃肿,其实SpringBoot早已考虑到了该问题,SpringBoot提供了**@PropertySource和@ImportResource**两个注解用于加载外部配置文件使用。
装配properties配置文件
在sources/config下创建一个yaml文件命名为user.properties内容与上方user的配置一样
Login类可如下写法
- @PropertySource(value = {"classpath:config/user.properties"})
- @Component
- @ConfigurationProperties(prefix = "user")
- public class Login{
- private String username;
- private String password;
- ...
运行一下,同样能达到加载配置效果
同时加载多个配置问题
细心的你,会发现@PropertySource注解中属性value为一个数组,如果同时加载多个配置文件,并且不同配置文件中对同一个属性设置了不同的值,那么Spring会识别哪一个呢?
带着疑问,我们可以通过控制变量法进行测试,具体过程再在赘述。
@PropertySource(value = {"classpath:config/user1.properties","classpath:config/user2.properties"})
结论:Spring加载顺序为从左到右顺序加载,后加载的会覆盖先加载的属性值。
如果你有强迫症,一定想加载yaml配置文件,那么可以通过PropertySourcesPlaceholderConfigurer类来加载yaml文件,将原来的user.properties改成user.yaml,Bean配置类中加入如下代码,Login配置类和一开始的方式一致。
- @Bean
- public static PropertySourcesPlaceholderConfigurer loadProperties() {
- PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();
- YamlPropertiesFactoryBean yaml = new YamlPropertiesFactoryBean();
- //yaml.setResources(new FileSystemResource("classpath:config/user.yml"));//File路径引入
- yaml.setResources(new ClassPathResource("config/user.yml"));//class路径引入
- configurer.setProperties(yaml.getObject());
- return configurer;
- }
运行一下,仍然可以能达到加载配置效果的
SpringBoot提出零xml的配置,因此SpringBoot默认情况下时不会识别项目中Spring的xml配置文件。为了能够加载xml的配置文件,SpringBoot提供了@ImportResource注解该注解可以加载Spring的xml配置文件,通常加于启动类上。
- @ImportResource(value = {"classpath:/beans.xml"})
- @SpringBootApplication(scanBasePackages = {"team.seagull.client"})
- public class DeployApplication {
- public static void main(String[] args) {
- SpringApplication.run(DeployApplication.class, args);
- }
- }
以下是Spring Boot配置文件优先级列表,从高到低排列:
1. 命令行参数:无法在目录结构中表示
1.1 file:./config/ 和 file:./:对应目录结构中的`config/`文件夹
- application-{profile}.properties
- application-{profile}.yml
- application.properties
- application.yml
1.2 嵌套在JAR包内:对应目录结构中的`target/your-application.jar/`
- application-{profile}.properties
- application-{profile}.yml
- application.properties
- application.yml
1.3 classpath:/config/ 和 classpath:/:对应目录结构中的`src/main/resources/`
- application-{profile}.properties
- application-{profile}.yml
- application.properties
- application.yml
2. 在@Configuration类上的@PropertySource注解指定的文件
3. 默认的配置文件(@PropertySource注解指定的文件)
4. 默认属性(使用@SpringBootApplication注解时,SpringApplication.setDefaultProperties方法设置的默认值)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。