Spring @PropertySource 读取属性文件

简介
Spring 中的@PropertySource 注解为读取属性文件提供了一种方便的声明式机制。属性文件包含键值对,例如app.log.level = 调试。在本文中,您将学习使用 @PropertySource 从属性文件中读取值,并使用 @Value 注释和 Environment 字段访问特定值。
1、将@PropertySource 与@Configuration 结合使用
@PropertySource 注释与@Configuration 注释一起使用。也可以在 XML 文件中定义属性源。当我们在类路径或内部资源中有属性文件时,我们可以指定如下。
@Configuration
@PropertySource("classpath:app.properties")
@ComponentScan("com.jsbd.propertysource")
public class AppConfig {
}
2、使用 @Value 注释访问值
我们将使用@PropertySource 读取属性文件并使用@Value("${}") 访问该文件中的值。
@Component
public class ConnectionManager {
@Value("${app.database.url}")
private String url;
@Value("${app.database.username}")
private String username;
}
完整的示例如下所示:
AppConfig.java
package com.jsbd.propertysource;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
@Configuration
@PropertySource("classpath:app.properties")
@ComponentScan("com.jsbd.propertysource")
public class AppConfig {
}
ConnectionManager.java
package com.jsbd.propertysource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.util.StringJoiner;
@Component
public class ConnectionManager {
@Value("${app.database.url}")
private String url;
@Value("${app.database.username}")
private String username;
@Value("${app.database.password}")
private String password;
@Value("${no.value}") //No value found
private String noValue;
@Override
public String toString() {
return new StringJoiner(", ", ConnectionManager.class.getSimpleName() + "[", "]")
.add("url='" + url + "'")
.add("username='" + username + "'")
.add("password='" + password + "'")
.add("noValue='" + noValue +"'")
.toString();
}
}
TestClass.java
package com.jsbd.propertysource;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class TestClass {
public static void main(String[] args) {
ApplicationContext context
= new AnnotationConfigApplicationContext(AppConfig.class);
System.out.println(context.getBean(ConnectionManager.class));
}
}
resources/app.properties
app.database.url=http://random-url
app.database.password=abcd@123
app.database.username=root
3、将@PropertySource 与Enviroment一起使用
Spring 官方文档推荐使用 Environment 接口从属性文件中访问任何属性。
@Component
public class AppLogger {
@Autowired
private Environment env;
public void printLogLevel() {
String logLevel = env.getProperty("app.log.level");
System.out.println(logLevel);
}
}
4、使用 @PropertySources 指定多个属性源
现在也可以在 Spring 中指定多个属性源。
@Configuration
@PropertySources({
@PropertySource("classpath:app.properties"),
@PropertySource("classpath:db.properties")
})
public class ApplicationConfig {
//...
}
如果没有找到一个或多个指定的 PropertySource 文件,spring 将抛出一个异常。
5、忽略属性文件未找到异常
有时,您可能希望应用忽略未找到属性源异常。当找不到指定的文件时,Spring 会抛出异常。
Caused by: java.io.FileNotFoundException:
class path resource [persistence.properties] cannot be opened because it does not exist
@Configuration
@PropertySource(value="classpath:persistence.properties", ignoreResourceNotFound=true)
public class AppConfig {
//...
}
6、占位符解析
Environment 集成在整个 Spring 容器中,它允许通过它解析占位符。下面是一个示例,显示了 xml 配置文件的导入,并且该文件的名称是动态注入的。
@Configuration
@ImportResource("classpth:${app.name}.xml")
public class AppConfig {
//
}
谁提供 app.name 值并不重要,这将起作用。可以说,我们不是从属性文件中分配这个值,而是使用 jvm 参数分配它,这将起作用。
java -jar -Dapp.name="jpa-example" JpaApp.jar
记住:
1、根据 Java 8 约定,@PropertySource 注释是可重复的。
2、但是,所有此类@PropertySource 注释都需要在同一级别声明,可以直接在配置类上声明,也可以作为同一自定义注释中的元注释。
3、不建议混合直接注释和元注释,因为直接注释有效地覆盖了元注释。
总结
在 Spring 中使用 @PropertySource 注解很简单。使用 @Value("${property.name}") 和 Environment 接口访问这些值。