前言
1 @Value+@PropertySource读取.properties配置文件
2 @Value+@PropertySource读取.yml配置文件
3 @ConfigurationProperties+@PropertySource读取.properties配置文件
4@ConfigurationProperties+@PropertySource读取.yml配置文件
使用 @ConfigurationProperties 注解可以将 application.yml 或 application.properties 主配置文件中的属性值与 Java Bean 对应属性进行注入。
此时如果所有属性值都配置在主配置文件中,主配置文件就会越来越庞大,这显然是不可以的。此时我们可以使用 Spring 为我们提供的 @PropertySource 注解,去加载指定的配置文件,然后结合 @ConfigurationProperties 注解,便能够实现指定配置文件与 Java Bean 的注入操作。
创建spring boot maven项目
4.0.0
org.***
LearnSpringBoot2-javaproject
1.0-SNAPSHOT
org.springframework.boot
spring-boot-starter-parent
2.3.4.RELEASE
org.springframework.boot
spring-boot-starter
org.springframework.boot
spring-boot-configuration-processor
8
8
UTF-8
org.springframework.boot
spring-boot-maven-plugin
新建一个 person.properties 配置文件,用来存放 Person 类的配置信息。接下来使用 @ PropertySource 注解,来实现通过读取该配置,实现配置文件与 Java Bean 类的注入操作。
#person.properties person.name=liqq person.staticpro=staticproValue person.hobbiess=game,tv,sing person.list=basketball tennis swim person.map={aa:"aa",bb:"bb"} person.age=28 person.birthday=2023-07-07 12:12:12 address.province=某某省 address.distinct= 某某市 address.county=某某区
Person类
package com.cect.ConfigurationPropertiesPackage;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.List;
import java.util.Map;
@Component
@PropertySource(value = {"classpath:person.properties"})
public class Person {
@Value("${person.name}")
private String name;
@Value("${person.staticpro:aa}")
public static String staticpro;
@Value("${person.hobbiess}")
private String[] hobbiess;
@Value("#{'${person.list:111 222 333}'.split(' ')}")
private List list;
@Value("#{${person.map:{'cc':'ccc','dd':'ddd'}}}")
private Map map;
@Value("#{address}")
private Address address;
@Value("#{T(java.io.File).separator}")
private String path;
@Value("#{T(java.lang.Math).random()}")
private double randomValue;
//注入时间属性需要使用@DateTimeFormat格式化或者使EL表达式
//@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
@Value(("#{new java.text.SimpleDateFormat(\"yyyy-MM-dd HH:mm:ss\").parse('${person.birthday}')}"))
private Date birthday;
@Value("#{systemProperties['os.name']}")
private String systemPropertiesName;
/*setter and getter */
}
Address类
package com.cect.ConfigurationPropertiesPackage;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
@Component
@PropertySource(value = {"classpath:person.properties"})
public class Address {
@Value("${address.province}")
private String province;
@Value("${address.distinct}")
private String distinct;
@Value("${address.county}")
private String county;
/*gette and setter method*/
}
pring Boot 默认不支持@PropertySource读取yaml 文件。
可以通过引入 PropertySourceFactory 接口使之成为可能。PropertySourceFactory 是PropertySource 的工厂类。默认实现是 DefaultPropertySourceFactory,可以构造ResourcePropertySource 实例。
注意:YAML 需要 SnakeYAML 1.18 或者更高版本。
@PropertySource 注解有一个
factory
属性,通过这个属性来入PropertySourceFactory
,这里给出YamlPropertySourceFactory
的例子
import org.springframework.core.io.support.PropertySourceFactory;
import java.io.IOException;
import java.util.Properties;
public class YamlPropertySourceFactory implements PropertySourceFactory {
@Override
public PropertySource> createPropertySource(String name, EncodedResource resource) throws IOException {
YamlPropertiesFactoryBean factory=new YamlPropertiesFactoryBean();
factory.setResources(resource.getResource());
factory.afterPropertiesSet();
Properties ymlProperties = factory.getObject();
String propertyName=name!=null?name:resource.getResource().getFilename();
return new PropertiesPropertySource(propertyName,ymlProperties);
}
}
package com.cect.ConfigurationPropertiesPackage;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.List;
import java.util.Map;
@Component
@PropertySource(value = {"classpath:person.yml"}, factory = YamlPropertySourceFactory.class)
public class Person {
@Value("${person.name}")
private String name;
@Value("${person.staticpro:aa}")
public static String staticpro;
@Value("${person.hobbiess}")
private String[] hobbiess;
@Value("#{'${person.list:111 222 333}'.split(' ')}")
private List list;
@Value("#{${person.map:{'cc':'ccc','dd':'ddd'}}}")
private Map map;
@Value("#{address}")
private Address address;
@Value("#{T(java.io.File).separator}")
private String path;
@Value("#{T(java.lang.Math).random()}")
private double randomValue;
//@Value(("#{new java.text.SimpleDateFormat(\"yyyy-MM-dd HH:mm:ss\").parse('${person.birthday}')}"))
@Value("${person.birthday}")
private Date birthday;
@Value("#{systemProperties['os.name']}")
private String systemPropertiesName;
/*setter and getter */
}
package com.cect.ConfigurationPropertiesPackage;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
@Component
@PropertySource(value = {"classpath:person.yml"}, factory = YamlPropertySourceFactory.class)
public class Address {
@Value("${address.province}")
private String province;
@Value("${address.distinct}")
private String distinct;
@Value("${address.county}")
private String county;
/*gette and setter method*/
}
person.yml
person: age: 27 name: scy staticpro: staticproValue hobbiess: game,tv,sing list: basketball tennis swim map: '{ aa: "aaa",bb: "bbb"}' birthday: 2022-01-07 12:12:12 address: province: 某某省 distinct: 某某市 county: 某某县
测试结果
person.properties
person.name=lixq person.staticpro=staticproValue person.hobbiess=game,tv,sing person.list=basketball,tennis,swim person.map.aa="aaa" person.map.bb="bbb" person.age=28 person.birthday=2023-07-08 13:13:13 address.province=某某省 address.distinct= 某某市 address.county=某某区
Person类
package com.cect.ConfigurationPropertiesPackage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.List;
import java.util.Map;
@Component
@ConfigurationProperties(prefix = "person")
@PropertySource(value = {"classpath:person.properties"})
public class Person {
private String name;
public static String staticpro;
private String[] hobbiess;
private List list;
private Map map;
@Autowired
private Address address;
private String path;
private double randomValue;
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
private Date birthday;
private String systemPropertiesName;
/*setter and getter */
}
Address类
package com.cect.ConfigurationPropertiesPackage;
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;
@Component
@ConfigurationProperties(prefix = "address")
@PropertySource(value = {"classpath:person.properties"})
public class Address {
private String province;
private String distinct;
private String county;
/*gette and setter method*/
}
测试类
package com.cect.ConfigurationPropertiesPackage;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
@SpringBootApplication
public class TestClass {
public static void main(String args[]){
ConfigurableApplicationContext context= SpringApplication.run(TestClass.class,args);
Person person = context.getBean("person",Person.class);
System.out.println("person.getList()="+person.getList().size());
System.out.println("person.getMap()="+person.getMap().toString());
System.out.println("person.getAddress()="+person.getAddress().toString());
System.out.println("person.getPath()="+person.getPath());
System.out.println("person.getRandomValue()="+person.getRandomValue());
System.out.println("person.getBirthday()="+person.getBirthday());
System.out.println("person.getSystemPropertiesName()="+person.getSystemPropertiesName());
System.out.println("person.getHobbiess().length="+person.getHobbiess().length);
System.out.println("person.getName()="+person.getName());
}
}
测试结果
person.yml
person: age: 27 name: scy staticpro: staticproValue hobbiess: game,tv,sing list: basketball tennis swim map: { "aa": "aaa","bb": "bbb"} birthday: 2022-01-07 12:12:12 address: province: 某某省 distinct: 某某市 county: 某某县
package com.cect.ConfigurationPropertiesPackage;
import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
import org.springframework.core.env.PropertiesPropertySource;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.support.EncodedResource;
import org.springframework.core.io.support.PropertySourceFactory;
import java.io.IOException;
import java.util.Properties;
public class YamlPropertySourceFactory implements PropertySourceFactory {
@Override
public PropertySource> createPropertySource(String name, EncodedResource resource) throws IOException {
YamlPropertiesFactoryBean factory=new YamlPropertiesFactoryBean();
factory.setResources(resource.getResource());
factory.afterPropertiesSet();
Properties ymlProperties = factory.getObject();
String propertyName=name!=null?name:resource.getResource().getFilename();
return new PropertiesPropertySource(propertyName,ymlProperties);
}
}
package com.cect.ConfigurationPropertiesPackage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.List;
import java.util.Map;
@Component
@ConfigurationProperties(prefix = "person")
@PropertySource(value = {"classpath:person.yml"},factory = YamlPropertySourceFactory.class)
public class Person {
private String name;
public static String staticpro;
private String[] hobbiess;
private List list;
private Map map;
@Autowired
private Address address;
private String path;
private double randomValue;
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
private Date birthday;
private String systemPropertiesName;
/*setter and getter */
}
package com.cect.ConfigurationPropertiesPackage;
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;
@Component
@ConfigurationProperties(prefix = "address")
@PropertySource(value = {"classpath:person.yml"},factory = YamlPropertySourceFactory.class)
public class Address {
private String province;
private String distinct;
private String county;
/*gette and setter method*/
}