Springboot读取配置文件
在springboot中配置文件的形式有两种,第一种是传统的properties形式,第二种是yml格式的文件,也是spring官方推荐的配置形式,结构比较清晰。
下面以一个简单的数据源配置来看一下两种配置文件的区别:
在properties种是这样的:
spring.datasource.url=jdbc:mysql://localhost:3306/consult spring.datasource.username=root spring.datasource.password=root spring.datasource.driver-class-name=com.mysql.jdbc.Driver
而在yml文件种是这样的:
spring: datasource: url: jdbc:mysql://localhost:3306/cfcc_pt username: root password: root driver-class-name: com.mysql.jdbc.Driver
从中不难看出,yml形式的配置更为简洁,易懂。
但两者的读取方式都是一样的。
1.首先在demo工程的pom文件中加入以下的依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!-- 支持 @ConfigurationProperties 注解 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency>
2.在resources源文件下新建application.yml文件,在这当中配置一个稍微复杂一点的结构:
myProps: simpleProp: simplePropValue arrayProps: 1,2,3,4,5 listMapProps: - name: abc value: abcValue - name: def value: defValue listStrProp: - strValue1 - strValue2 mapProps: key1: value1 keys: value2
从配置文件中分析可知,它的根节点为myProps,
1.他的第一个属性为simpleProp,值是一个字符串;
2.第二个属性为arrayProps,值是一个包含五个整型的数组;
3.第三个属性可以理解为一个list里面装了一个map,里面有两条数据;
4.第四个属性则是一个list里面装的string字符串;
5.第五个则是一个map集合里面包含两个键值对。
理解了该配置的结构属性,再依照此结构写出对应的Java实体类就很容易了。
3.新建配置文件实体类
package com.cfcc.prop; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; import java.util.List; import java.util.Map; @Component @ConfigurationProperties(prefix = "myProps") public class MyProps { private String simpleProp; private String[] arrayProps; private List<Map<String, String>> listMapProps; private List<String> listStrProp; private Map<String, String> mapProps; private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSimpleProp() { return simpleProp; } public void setSimpleProp(String simpleProp) { this.simpleProp = simpleProp; } public String[] getArrayProps() { return arrayProps; } public void setArrayProps(String[] arrayProps) { this.arrayProps = arrayProps; } public List<Map<String, String>> getListMapProps() { return listMapProps; } public void setListMapProps(List<Map<String, String>> listMapProps) { this.listMapProps = listMapProps; } public List<String> getListStrProp() { return listStrProp; } public void setListStrProp(List<String> listStrProp) { this.listStrProp = listStrProp; } public Map<String, String> getMapProps() { return mapProps; } public void setMapProps(Map<String, String> mapProps) { this.mapProps = mapProps; } }@Component将该实体类交给spring容器进行管理
@ConfigurationProperties(prefix = "myProps")读取所有以myProps开始的配置。
4.新建一个controller来读取上面配置的属性。
package com.cfcc.controller; import com.cfcc.prop.JdbcTest; import com.cfcc.prop.MyProps; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.core.env.Environment; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/read") public class UserController { @Autowired private MyProps myProps; @Autowired private ObjectMapper mapper; @RequestMapping("/yml") public String ymlTest() throws JsonProcessingException { System.out.println("simpleProp:"+myProps.getSimpleProp()); System.out.println("arrayProps:"+mapper.writeValueAsString(myProps.getArrayProps())); System.out.println("listMapProps:"+mapper.writeValueAsString(myProps.getListMapProps())); System.out.println("listStrProp:"+mapper.writeValueAsString(myProps.getListStrProp())); System.out.println("mapProps:"+mapper.writeValueAsString(myProps.getMapProps())); return " read yml"; } }
在浏览器的地址栏输入localhost:8080/read/yml
控制台就会输出对应的值。这里借助了ObjectMapper将其中的一些对象转换成了字符串进行输出,方便查看。
在项目的开发过程中,不仅需要读取application配置文件中的内容,有时我们也会自己定义一些配置文件,那么又应该怎样来读取呢。
5.读取自定义的配置文件
在resources下面新建config文件夹,在下面新建一个test.properties文件,加入以下配置:
com.jxc.name=kevin com.jxc.age=23 com.jxc.addr=chengdu com.jxc.desc=${com.jxc.name}${com.jxc.age}岁住在${com.jxc.addr} # 随机字符串 com.didispace.blog.value=${random.value} # 随机int com.didispace.blog.number=${random.int} # 随机long com.didispace.blog.bignumber=${random.long} # 10以内的随机数 com.didispace.blog.test1=${random.int(10)} # 10-20的随机数 com.didispace.blog.test2=${random.int[10,20]}
在配置文件中引入当前配置中的属性使用${属性名}即可,random是系统定义好了的一个对象,可以直接拿来调用。
6.定义读取配置文件的配置类。
package com.cfcc; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; /** * 加载properties配置文件,在方法中可以获取 * kevin.properties文件不存在,验证ignoreResourceNotFound属性 * 加上encoding = "utf-8"属性防止中文乱码,不能为大写的"UTF-8" */ @Configuration @PropertySource( value = {"classpath:/config/test.properties","classpath:/config/kevin.properties"},ignoreResourceNotFound = true, encoding = "utf-8") public class PropertiesConfig { // PropertySourcesPlaceholderConfigurer这个bean, // 这个bean主要用于解决@value中使用的${…}占位符。 // 假如你不使用${…}占位符的话,可以不使用这个bean。 @Bean public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer(){ return new PropertySourcesPlaceholderConfigurer(); } }
7.读取配置
这里用到了@PropertySource这个注解,在该注解中加入我们定义好的配置文件的路径,下面这个bean主要为了使我们可以使用@Value这个注解来读取配置。
在controller中注入
@Autowired private Environment environment; @Value("${com.jxc.age}") private String age;
Environment对象用于读取上面自定义的属性,@Value则是spring里面封装的读取配置文件的一个注解。
@RequestMapping("/prop") public String propTest(){ //测试加载properties文件 System.out.println("name:"+environment.getProperty("com.jxc.name")); System.out.println("age:"+age); System.out.println("addr:"+environment.getProperty("com.jxc.addr")); System.out.println("描述:"+environment.getProperty("com.jxc.desc")); System.out.println("随机数:"); System.out.println("随机字符串:"+environment.getProperty("com.didispace.blog.value"));//32位 System.out.println("随机int:"+environment.getProperty("com.didispace.blog.number")); System.out.println("随机long:"+environment.getProperty("com.didispace.blog.bignumber")); System.out.println("10以内的随机数:"+environment.getProperty("com.didispace.blog.test1")); System.out.println("10-20的随机数:"+environment.getProperty("com.didispace.blog.test2")); return "read properties"; }
同理在浏览器中输入localhost:8080/read/prop,控制台就会输出对应的信息。
8.多环境的配置文件读取
在我们的系统开发中,一套程序要适应多个应用环境,如开发、、测试、生产等,其中每个环境的配置都不一样,如果每次都去修改配置的话,那就会变得相当的繁琐。在springboot中提供了一套支持多环境的配置。
在Spring Boot中多环境配置文件名需要满足application-{profile}.properties的格式,其中{profile}对应你的环境标识,比如:
application-dev.properties:开发环境
application-test.properties:测试环境
application-prod.properties:生产环境
至于哪个具体的配置文件会被加载,需要在application.properties文件中通过spring.profiles.active属性来设置,其值对应{profile}值。
下面来测试一下这个多环境的配置:
首先在resources下新建application-dev.yml
加入以下配置:
jdbcTest: name: mysql
再新建一个application-test.yml
加入以下配置:
jdbcTest: name: oracle两者配置的属性一样,只是值不一样,要想读取当中的配置,需要再application.yml加入这个配置。
spring: #多环境的配置文件选择 profiles: active: dev
新建JcbcTest配置类:
package com.cfcc.prop; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; @Component @ConfigurationProperties(prefix = "jdbcTest") public class JdbcTest { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } }
在controller中注入这个类,新建方法进行读取。
@Autowired private JdbcTest jdbcTest;
@RequestMapping("/more") public String getMoreEnv(){ System.out.println("多环境配置:"+jdbcTest.getName()); return "env"; }
在浏览器中输入localhost:8080/read/more,控制台就会输出mysql。
修改修改配置文件中的active值为test,则会输出oracle。