使用 @PropertySource 将 .properties 文件中的所有值注入属性(或映射)

Posted

技术标签:

【中文标题】使用 @PropertySource 将 .properties 文件中的所有值注入属性(或映射)【英文标题】:Inject all values from .properties file into Properties (or Map) using @PropertySource 【发布时间】:2021-11-13 04:45:03 【问题描述】:

我在使用 Spring JDBC 与数据库交互的应用程序中使用 Spring Framework 版本 5.3.10

我正在尝试将 SQL 查询隔离到 .properties 文件中。我知道有很多方法可以做到这一点,但我想知道是否有办法将@PropertySource("classpath:database/queries.properties") 引用的给定.properties 文件的所有值注入Properties(或Map)类型。

例如,如果我有一个像这样的“存储库”(或 DAO,你可以命名它)类:

@Repository
@RequiredArgsConstructor
@PropertySource("classpath:database/queries.properties")
public class ThisJdbc implements IThisJdbc 
  private final Map<String, String> sqlStore; // ...values from queries.properties here

  private final Properties sqlStore; // ...or here

  @Override
  public int[] batchInsert(final List<This> these) 
    sqlStore.get("batch-insert");
    ...
  

  ...

我想要一种简单的方法来注入通过上述类型提供给该类的.properties 文件中的内容——或任何其他可用的键/值类型。 .properties 文件和往常一样:

find-all = select * from tb_this

find-by-col_1 = select * from tb_this where col_1 = :col_1

insert-record = insert into tb_this values (:col_1, :col_2, :col_3)

请注意,在所有这些类中注入 Environment 对我来说不是一个选项;)

我一直在寻找一种使用带有固定前缀的@Value 的方法——类似于 Spring Boot 的@ConfigurationProperties,但我找不到任何相关的东西。

基本上,我想看看是否有办法使用@PropertySource 和任何类似Map 的类型来避免这种情况:

@Bean(name = "this-queries")
public PropertiesFactoryBean thisQueries() 
  final var bean = new PropertiesFactoryBean();
  bean.setLocation(new ClassPathResource("database/queries.properties"));
  return bean;

【问题讨论】:

【参考方案1】:

@PropertySource 将与@Configuration 类一起使用。话虽如此,请尝试以下操作:

@Repository
@Configuration
@RequiredArgsConstructor
@PropertySource("classpath:database/queries.properties")
public class ThisJdbc implements IThisJdbc 
  @Value("#$queries")
  private final Map<String, String> sqlStore; // ...values from queries.properties here

  @Override
  public int[] batchInsert(final List<This> these) 
    sqlStore.get("batch-insert");
    ...
  

  ...

假设您的queries.properties 是:

queries = key1:'query1',key2:'query2',....

【讨论】:

我目前没有使用Spring Boot,而只是Spring Framework;我无法使用@ConfigurationProperties 在这种情况下,我已经编辑了我的答案。请检查一下。 SpEl 表达式抛出如下内容:SpelParseException: EL1041E: After parsing a valid expression, there is still more data in the expression: 'lcurly()'。你试过这个并为你工作吗?我实际上并不完全理解 $queries.properties 将什么值带入 SpEl 表达式。 我的错,我看错了你的代码。我已经更新了我的答案。

以上是关于使用 @PropertySource 将 .properties 文件中的所有值注入属性(或映射)的主要内容,如果未能解决你的问题,请参考以下文章

Spring——15使用@PropertySource加载配置文件

使用带有外部 JSON 文件的 @PropertySource 的 Spring 属性配置

SpringBoot系列之@PropertySource和@Value注解

Jar 中的 @PropertySource 用于类路径上的外部文件

SpringBoot项目使用@PropertySource注解加载properties配置文件,但输出对象值为null

Springboot中PropertySource注解的使用