Spring Boot获取文件总的来说有三种方式,分别是@Value注解,@ConfigurationProperties注解和Environment接口。这三种注解可以配合着@PropertySource来使用,@PropertySource主要是用来指定具体的配置文件。
@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;}
- value():指定配置文件
- encoding():指定编码,因为properties文件的编码默认是ios8859-1,读取出来是乱码
factory():自定义解析文件类型,因为该注解默认只会加载properties文件,如果想要指定yml等其他格式的文件需要自定义实现。
一、@Value注解读取文件
新建两个配置文件config.properties和configs.properties,分别写入如下内容:
zhbin.config.web-configs.name=Java旅途zhbin.config.web-configs.age=22
zhbin.config.web-configs.name=Java旅途zhbin.config.web-configs.age=18
新增一个类用来读取配置文件
@Configuration@PropertySource(value = {"classpath:config.properties"},encoding="gbk")public class GetProperties {@Value("${zhbin.config.web-configs.name}")private String name;@Value("${zhbin.config.web-configs.age}")private String age;public String getConfig() {return name+"-----"+age;}}
如果想要读取yml文件,则我们需要重写DefaultPropertySourceFactory,让其加载yml文件,然后在注解
@PropertySource上自定factory。代码如下:public class YmlConfigFactory extends DefaultPropertySourceFactory {@Overridepublic PropertySource<?> createPropertySource(String name, EncodedResource resource) throws IOException {String sourceName = name != null ? name : resource.getResource().getFilename();if (!resource.getResource().exists()) {return new PropertiesPropertySource(sourceName, new Properties());} else if (sourceName.endsWith(".yml") || sourceName.endsWith(".yaml")) {Properties propertiesFromYaml = loadYml(resource);return new PropertiesPropertySource(sourceName, propertiesFromYaml);} else {return super.createPropertySource(name, resource);}}private Properties loadYml(EncodedResource resource) throws IOException {YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();factory.setResources(resource.getResource());factory.afterPropertiesSet();return factory.getObject();}}
@PropertySource(value = {"classpath:config.properties"},encoding="gbk",factory = YmlConfigFactory.class)
二、Environment读取文件
配置文件我们继续用上面的两个,定义一个类去读取配置文件
@Configuration@PropertySource(value = {"classpath:config.properties"},encoding="gbk")public class GetProperties {@AutowiredEnvironment environment;public String getEnvConfig(){String name = environment.getProperty("zhbin.config.web-configs.name");String age = environment.getProperty("zhbin.config.web-configs.age");return name+"-----"+age;}}
三、@ConfigurationProperties读取配置文件
@ConfigurationProperties可以将配置文件直接映射成一个实体类,然后我们可以直接操作实体类来获取配置文件相关数据。
新建一个yml文件,当然properties文件也没问题zhbin:config:web-configs:name: Java旅途age: 20
新建实体类用来映射该配置
@Component@ConfigurationProperties(prefix = "zhbin.config")@Datapublic class StudentYml {// webConfigs务必与配置文件相对应,写为驼峰命名方式private WebConfigs webConfigs = new WebConfigs();@Datapublic static class WebConfigs {private String name;private String age;}}
prefix = “zhbin.config”用来指定配置文件前缀
如果需要获取list集合,则做以下修改即可。
zhbin:config:web-configs:- name: Java旅途age: 20- name: Java旅途2age: 202
@Component@ConfigurationProperties(prefix = "zhbin.config")@Datapublic class StudentYml {private List<WebConfigs> webConfigs = new ArrayList<>();@Datapublic static class WebConfigs {private String name;private String age;}}
通过@ConfigurationProperties读取并校验
我们先将application.yml修改为如下内容,明显看出这不是一个正确的 email 格式:
my-profile:name: Guide哥email: koushuangbwcx@复制代码
ProfileProperties类没有加@Component注解。我们在我们要使用ProfileProperties的地方使用@EnableConfigurationProperties注册我们的配置 bean:
import lombok.Getter;import lombok.Setter;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.Email;import javax.validation.constraints.NotEmpty;/*** @author shuang.kou*/@Getter@Setter@ToString@ConfigurationProperties("my-profile")@Validatedpublic class ProfileProperties {@NotEmptyprivate String name;@NotEmptyprivate String email;//配置文件中没有读取到的话就用默认值private Boolean handsome = Boolean.TRUE;}复制代码
具体使用:
package cn.javaguide.readconfigproperties;import org.springframework.beans.factory.InitializingBean;import org.springframework.beans.factory.annotation.Value;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.boot.context.properties.EnableConfigurationProperties;/*** @author shuang.kou*/@SpringBootApplication@EnableConfigurationProperties(ProfileProperties.class)public class ReadConfigPropertiesApplication implements InitializingBean {private final ProfileProperties profileProperties;public ReadConfigPropertiesApplication(ProfileProperties profileProperties) {this.profileProperties = profileProperties;}public static void main(String[] args) {SpringApplication.run(ReadConfigPropertiesApplication.class, args);}@Overridepublic void afterPropertiesSet() {System.out.println(profileProperties.toString());}}
因为我们的邮箱格式不正确,所以程序运行的时候就报错,根本运行不起来,保证了数据类型的安全性:
Binding to target org.springframework.boot.context.properties.bind.BindException: Failed to bind properties under 'my-profile' to cn.javaguide.readconfigproperties.ProfileProperties failed:Property: my-profile.emailValue: koushuangbwcx@Origin: class path resource [application.yml]:5:10Reason: must be a well-formed email address
我们把邮箱测试改为正确的之后再运行,控制台就能成功打印出读取到的信息:
ProfileProperties(name=Guide哥, email=koushuangbwcx@163.com, handsome=true)
@PropertySource读取指定 properties 文件
import lombok.Getter;import lombok.Setter;import org.springframework.beans.factory.annotation.Value;import org.springframework.context.annotation.PropertySource;import org.springframework.stereotype.Component;@Component@PropertySource("classpath:website.properties")@Getter@Setterclass WebSite {@Value("${url}")private String url;}复制代码
使用:
@Autowiredprivate WebSite webSite;System.out.println(webSite.getUrl());//https://javaguide.cn/
