日积月累,水滴石穿 😄
前言
在
Spring Boot
中,默认加载的配置文件名称为
application.properties
或者为
application.yml
。会将属性文件的值加载到
Spring
的
Environment
中。可以使用
@Value
和
@ConfigurationProperties
进行取值。
application.properties
、
application.yml
我们可以称为主配置文件,但是在实际开发中,我们不可能将所有的配置放在主配置文件中,日积月累,主配置文件就会越来越庞大,难以维护。所以需要进行拆分,比如数据库配置、redis配置、微信配置,我们可以分别拆分为:
datasource.properties(yml)
、
redis.properties
、
wx.properties
。
可惜我们自定义的配置文件并不会被自动加载,我们需要使用
Spring
提供的
@PropertySource
注解,去加载指定的配置文件。
依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.2.1.RELEASE</version>
</dependency>
未使用注解
配置文件
小杰提供了两个配置文件,
application.properties
和
juejin.properties
,文件内容如下:
blog.name = cxyxj
juejin.home = https://juejin.cn/user/2164257578290398
测试
@SpringBootApplication(scanBasePackages = "com.cxyxj.propertysource")
public class AppMain {
public static void main(String[] args) {
ConfigurableApplicationContext application = SpringApplication.run(AppMain.class);
//获得容器的 Environment
Environment env = application.getEnvironment();
//根据key获取
String blog = env.getProperty("blog.name");
String juejin = env.getProperty("juejin.home");
System.out.println(blog);
System.out.println(juejin);
cxyxj
null
看到
juejin.home
并没有被加载到
Environment
对象中。
使用注解加载指定properties
@PropertySource("juejin.properties")
cxyxj
https://juejin.cn/user/2164257578290398
@PropertySource注解定义
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Repeatable(PropertySources.class)
public @interface PropertySource {
String name() default "";
String[] value();
boolean ignoreResourceNotFound() default false;
String encoding() default "";
Class<? extends PropertySourceFactory> factory() default PropertySourceFactory.class;
}
先来看一下
PropertySource
类上的注解,一共有四个,
@Target
、
@Retention
、
@Documented
这三个是元注解,不过多介绍。还有一个是
@Repeatable
,它有什么作用呢?如果我们希望一个注解在一个类上重复标注,可以在注解上加
@Repeatable
。效果如下:
接下来看看注解中的属性。
加载指定xml文件
-
先创建一个名为
juejin.xml
的xml 文件,内容如下:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<entry key="juejin.home">https://juejin.cn/user/2164257578290398</entry>
</properties>
@PropertySource(name = "juejin", value = {"juejin.xml"})
cxyxj
https://juejin.cn/user/2164257578290398
加载 yml
上面说过,
@PropertySource
只支持
properties
和
XML
的属性文件格式,这肯定是不行的,现在
yml
越来越流行了。那如何让
@PropertySource
支持
yml
文件格式呢?这时候就需要使用到
factory
属性了,指定
PropertySourceFactory
进行加载。
juejin:
home: https://juejin.cn/user/2164257578290398
-
创建
YmlPropertyResourceFactory
类,并实现
PropertySourceFactory
,重写
createPropertySource
方法。
import org.springframework.boot.env.YamlPropertySourceLoader;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.support.DefaultPropertySourceFactory;
import org.springframework.core.io.support.EncodedResource;
import org.springframework.core.io.support.PropertySourceFactory;
import java.io.IOException;
import java.util.List;
import java.util.Optional;
* 在 @PropertySource 注解的 factory属性指定 YmlPropertyResourceFactory 类,则可以支持读取 yml
* @author: cxyxj
* @create: 2022-01-21 15:35
public class YmlPropertyResourceFactory implements PropertySourceFactory {
private static String YML = ".yml";
private static String YAML = ".yaml";
* @param name:@PropertySource 注解 name 的值
* @param resource:资源
@Override
public PropertySource<?> createPropertySource(String name, EncodedResource resource) throws IOException {
// 文件名称
String filename = resource.getResource().getFilename();
// 属性源的名称
String resourceName = Optional.ofNullable(name).orElse(filename);
if (filename.endsWith(YML) || filename.endsWith(YAML)) {
List<PropertySource<?>> yamlSources = new YamlPropertySourceLoader().load(resourceName, resource.getResource());
return yamlSources.get(0);
} else {
// 其他文件后缀
return new DefaultPropertySourceFactory().createPropertySource(name, resource);
}
@PropertySource(name = "juejin", value = {"juejin.yml"},factory = YmlPropertyResourceFactory.class)
cxyxj
https://juejin.cn/user/2164257578290398
-
如你对本文有疑问或本文有错误之处,欢迎评论留言指出。如觉得本文对你有所帮助,欢迎点赞和关注。
`SpringBoot2.2`版本发行后一些新的功能也渐渐的浮出了水面,在之前版本`SpringBoot`的配置文件与类之间的属性绑定(`@ConfigurationProperties`)是通过`Setter`方法来进行绑定对应的配置值,而从`2.2`版本开始支持了`构造函数`的方式进行绑定。