Spring @PropertySource 读取属性文件

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 接口访问这些值。

版权声明:著作权归作者所有。

thumb_up 0 | star_outline 0 | textsms 0