@Value
注解获取在任意Bean
对象种通过@Value
注解可以获取到对应的配置信息,代码样例如下:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.PropertiesFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.AbstractEnvironment;
import org.springframework.core.env.EnumerablePropertySource;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.ClassPathResource;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Properties;
@Configuration
public class ClassPathProp {
@Value("${prop.value.key_1}")
private String valueKey_1;
@Value("${prop.value.key_2}")
private String valueKey_2;
@Bean(name = "propertiesByValue")
public Properties getPropertiesByValue() {
Properties res = new Properties();
res.put("prop.value.key_1", valueKey_1);
res.put("prop.value.key_2", valueKey_2);
return res;
}
}
优缺点分析:
Environment
对象获取在任务Bean
对象中注入Environment
对象后,通过Environment
对象提供的getProperty(String name)
方法可以获取到对应的配置信息,代码样例:
@Configuration
public class ClassPathProp {
@Autowired
private AbstractEnvironment env;
@Bean(name = "propertiesByEnv")
public Properties getPropertiesByEnv() {
Properties res = new Properties();
final String key_1="prop.env.envKey.name";
final String key_2="prop.env.envKey.val";
res.put(key_1,this.env.getProperty(key_1));
res.put(key_2,this.env.getProperty(key_2));
return res;
}
}
优缺点分析:
@ConfigurationProperties
注解获取创建一个pojo
对象,使用@ConfigurationProperties
注解说明配置项的前缀,使用这种方法必须保证类的属性名和配置文件中的配置项名称一致,驼峰命名xxxXxx
对应配置文件中的xxx-xxx
,对于多层属性,需要创建静态内部类获取配置信息。代码示例:
package top.sunyog.spring.notes.prop;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.Properties;
@Component
@ConfigurationProperties(prefix = "prop.app")
public class AppProperties {
private String testKey;
private String dbKey;
private AppDatasource appDatasource;
public AppDatasource getAppDatasource() {
return appDatasource;
}
public void setAppDatasource(AppDatasource appDatasource) {
this.appDatasource = appDatasource;
}
public String getTestKey() {
return testKey;
}
public void setTestKey(String testKey) {
this.testKey = testKey;
}
public String getDbKey() {
return dbKey;
}
public void setDbKey(String dbKey) {
this.dbKey = dbKey;
}
/**
* 多层配置信息,需要添加静态内部类,静态内部类实现getter,setter方法
*/
public static class AppDatasource{
private String dbType;
private Integer dbCount;
public String getDbType() {
return dbType;
}
public void setDbType(String dbType) {
this.dbType = dbType;
}
public Integer getDbCount() {
return dbCount;
}
public void setDbCount(Integer dbCount) {
this.dbCount = dbCount;
}
}
public Properties getProperties(){
Properties res = new Properties();
res.put("testKey",this.testKey);
res.put("dbKey",this.dbKey);
res.put("appDatasource.dbCount",this.appDatasource.dbCount);
res.put("appDatasource.dbType",this.appDatasource.dbType);
return res;
}
}
优缺点分析:
@PropertySource
注解获取(方法三的变种)通过@PropertySource
注解说明配置文件的路径,可以获取到对应配置文件中的配置信息,代码样例:
package top.sunyog.spring.notes.prop;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
import java.util.Properties;
@Component
@PropertySource(value = "classpath:config/source.properties",encoding = "UTF-8",ignoreResourceNotFound = true)
@ConfigurationProperties(prefix = "config")
public class SourceProperties {
private String username;
private String password;
private String url;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public Properties getProperties(){
Properties res = new Properties();
res.put("username",this.getUsername());
res.put("password",this.password);
res.put("url",this.url);
return res;
}
}
优缺点分析:
PropertiesFactoryBean
对象获取配置信息创建一个PropertiesFactoryBean
对象,设定好资源位置后,通过getObject()
方法可以获取到该位置下的所有配置信息,代码样例:
@Configuration
public class ClassPathProp {
private final String PROPERTIES_PATH = "application.properties";
@Bean(name = "propertiesByPath")
public Properties getPropertiesByPath() throws IOException {
PropertiesFactoryBean propFactoryBean = new PropertiesFactoryBean();
propFactoryBean.setLocation(new ClassPathResource(this.PROPERTIES_PATH));
propFactoryBean.afterPropertiesSet();
return propFactoryBean.getObject();
}
优缺点分析:
jdk
提供了Properties
对象,可以通过输入流直接读取配置文件,代码样例:
@Configuration
public class ClassPathProp {
@Bean(name = "propertiesByStream")
public Properties getPropertiesByStream() throws IOException {
Properties res = new Properties();
InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("config/setting.properties");
InputStreamReader reader = new InputStreamReader(inputStream);
res.load(reader);
reader.close();
inputStream.close();
return res;
}
}
优缺点分析:
EnumerablePropertySource
对象获取到所有配置项AbstractEnvironment
对象中存在一个getPropertySources()
方法,可以用来获取所有属性资源,其中EnumerablePropertySource
类用来存储所有配置属性,可通过它的.getPropertyNames()
方法获取所有配置项的名称。代码样例:
@Configuration
public class ClassPathProp {
@Bean(name = "propertiesAll")
public Properties getAllPropertiesByEnv() {
Properties res = new Properties();
MutablePropertySources sources = env.getPropertySources();
for (PropertySource<?> source : sources) {
if (source instanceof EnumerablePropertySource) {
String[] names = ((EnumerablePropertySource<?>) source).getPropertyNames();
for (String name : names) {
res.put(name, source.getProperty(name));
}
}
}
return res;
}
}
优缺点分析:
样例代码对应的配置文件如下:
application.properties
文件server.port=18080
spring.application.name=notes
prop.value.key_1=key_1
prop.value.key_2=key_2
prop.env.envKey.name=envKey
prop.env.envKey.val=1000
prop.app.testKey=junit
prop.app.dbKey=mysql 5.8
prop.app.app-datasource.db-type=mysql
prop.app.app-datasource.db-count=3
config/setting.properties
文件setting.function.name=method
setting.function.param=json
setting.field.name=pro
setting.field.val=str
config/source.properties
文件config.username=root
config.password=abcd@
config.url=https://test.top
测试打印配置内容相关代码:
package top.sunyog.spring.notes.auto;
import org.springframework.beans.BeansException;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import top.sunyog.spring.notes.prop.AppProperties;
import top.sunyog.spring.notes.prop.SourceProperties;
import java.text.MessageFormat;
import java.util.Map;
import java.util.Properties;
/*
* 项目启动后立即执行该代码
*/
@Component
public class PropertiesInfoRunner implements ApplicationRunner, ApplicationContextAware {
private ApplicationContext context;
@Override
public void run(ApplicationArguments args) throws Exception {
//测试使用Environment对象读取所有配置
String envAllType = "propertiesAll";
Object propertiesEnvAll = context.getBean(envAllType);
this.printProperties(envAllType,((Properties) propertiesEnvAll));
//测试使用PropertyFactoryBean对象读取配置
String pathType = "propertiesByPath";
Object propertiesByPath = context.getBean(pathType);
this.printProperties(pathType,((Properties) propertiesByPath));
//测试使用@Value注解读取配置
String valueType = "propertiesByValue";
Object propertiesByValue = context.getBean(valueType);
this.printProperties(valueType,((Properties) propertiesByValue));
//测试使用Environment对象读取配置
String envType = "propertiesByEnv";
Object propertiesByEnv = context.getBean(envType);
this.printProperties(envType,((Properties) propertiesByEnv));
//测试使用@ConfigurationProperties注解读取配置
String appType="propertiesApp";
AppProperties appProperty = context.getBean(AppProperties.class);
this.printProperties(appType,appProperty.getProperties());
//测试使用@PropertySource注解读取配置
String sourceType="propertiesSource";
SourceProperties sourceProperty = context.getBean(SourceProperties.class);
this.printProperties(sourceType,sourceProperty.getProperties());
//测试jdk原生方法读取配置
String jdkType="propertiesByStream";
Object propertiesByStream = context.getBean(jdkType);
this.printProperties(jdkType, ((Properties) propertiesByStream));
}
private void printProperties(String type,Properties properties) {
//左{需要使用单引号包裹,否则格式化时报错
final String msgFormat="{0}:=====>'{'key = {1}, value = {2}}";
for (Map.Entry<Object, Object> entry : properties.entrySet()) {
System.out.println(MessageFormat.format(msgFormat,type,entry.getKey(),entry.getValue()));
}
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.context = applicationContext;
}
}
打印内容如下:
Connected to the target VM, address: '127.0.0.1:13426', transport: 'socket'
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.3.12.RELEASE)
2022-07-28 14:23:24.089 INFO 5040 --- [ main] t.s.spring.notes.SpringNotesApplication : Starting SpringNotesApplication on DESKTOP-MVSU4U6 with PID 5040 (D:\Activities\code\springboot\springboot-notes\target\classes started by Myste in D:\Activities\code\springboot)
2022-07-28 14:23:24.091 INFO 5040 --- [ main] t.s.spring.notes.SpringNotesApplication : No active profile set, falling back to default profiles: default
2022-07-28 14:23:24.481 INFO 5040 --- [ main] t.s.spring.notes.SpringNotesApplication : Started SpringNotesApplication in 0.651 seconds (JVM running for 0.957)
此处省略一堆。。。
propertiesAll:=====>{key = intellij.debug.agent, value = true}
propertiesAll:=====>{key = DriverData, value = 简略。。。}
propertiesAll:=====>{key = IDEA_INITIAL_DIRECTORY, value = 简略。。。}
propertiesByPath:=====>{key = prop.app.testKey, value = junit}
propertiesByPath:=====>{key = prop.app.app-datasource.db-type, value = mysql}
propertiesByPath:=====>{key = server.port, value = 18080}
propertiesByPath:=====>{key = prop.app.dbKey, value = mysql 5.8}
propertiesByPath:=====>{key = prop.env.envKey.val, value = 1000}
propertiesByPath:=====>{key = prop.value.key_2, value = key_2}
propertiesByPath:=====>{key = prop.value.key_1, value = key_1}
propertiesByPath:=====>{key = prop.app.app-datasource.db-count, value = 3}
propertiesByPath:=====>{key = spring.application.name, value = notes}
propertiesByPath:=====>{key = prop.env.envKey.name, value = envKey}
propertiesByValue:=====>{key = prop.value.key_2, value = key_2}
propertiesByValue:=====>{key = prop.value.key_1, value = key_1}
propertiesByEnv:=====>{key = prop.env.envKey.name, value = envKey}
propertiesByEnv:=====>{key = prop.env.envKey.val, value = 1000}
propertiesApp:=====>{key = appDatasource.dbType, value = mysql}
propertiesApp:=====>{key = appDatasource.dbCount, value = 3}
propertiesApp:=====>{key = dbKey, value = mysql 5.8}
propertiesApp:=====>{key = testKey, value = junit}
propertiesSource:=====>{key = url, value = https://test.top}
propertiesSource:=====>{key = password, value = abcd@}
propertiesSource:=====>{key = username, value = root}
propertiesByStream:=====>{key = setting.function.param, value = json}
propertiesByStream:=====>{key = setting.field.val, value = str}
propertiesByStream:=====>{key = setting.function.name, value = method}
propertiesByStream:=====>{key = setting.field.name, value = pro}
Disconnected from the target VM, address: '127.0.0.1:13426', transport: 'socket'
Process finished with exit code 0
项目目录结构如下: