【问题标题】:How to inject multiple basePackages from a YAML file in @EnableJpaRepositories如何从@EnableJpaRepositories 中的 YAML 文件注入多个 basePackage
【发布时间】:2018-01-29 09:25:15
【问题描述】:

我想允许我的一个库的用户指定他们的 JPA 实体和 Spring Data JPA 存储库的位置,例如:

database1:
  datasource:
    repository-package: com.sample.database1.repositories1,com.sample.database1.repositories2
    entity-packages: com.sample.database1.entities1,com.sample.database1.entities2

我的库定义:

@Configuration
@EnableJpaRepositories(basePackages = "${database1.datasource.repository-package}",
        entityManagerFactoryRef = "database1EntityManagerFactory",
        transactionManagerRef = "database1TransactionManager")
static class Database1DataSourceAutoConfiguration {

    @Value("${database1.datasource.entity-packages}")
    private String[] entityPackages;

entityPackages 被正确注入,包含一个带有两个实体包的数组。

但是,basePackages = "${database1.datasource.repository-package}" 显然不起作用,因为它引用的是字符串 "com.sample.database1.repositories1,com.sample.database1.repositories2",而不是包含两个字符串的数组。

有没有办法可以将 YML 文件中的 String[] 注入到该注释属性中?如果没有,有什么解决方法吗?

@EnableJpaRepositories(basePackages = { ??? }

【问题讨论】:

标签: spring spring-boot spring-data spring-data-jpa


【解决方案1】:

由于@EnableJpaRepositories 不解析表达式语言,您将无法将包列表作为单个环境属性提供。

另一种方法是在属性值中使用通配符来匹配您需要扫描的所有包:

database1.datasource.entity-packages=com.sample.database1.repositories*

Spring 会将其解析为基于“/”的资源路径,然后扫描:

classpath*:com/sample/database1/repositories*/*.class

【讨论】:

  • 您不能在@EnableJpaRepositories 注释属性中使用属性占位符来获取一些包而不是一个带有属性占位符的字符串,但是您可以在其中制作自己的“@EnableJpaRepositoriesWithProperties”注释将工作,请参阅以下答案:stackoverflow.com/questions/47635650/…
【解决方案2】:

你可以自定义你自己的EnableJpaRepository注解。我用过那个实现的多数据源,可以设置任何我想要的“basePackages”。

try this

【讨论】:

  • 这种方法有效。我相信这应该是公认的答案。其他答案只是表明这是不可能的。
【解决方案3】:

不确定,但我认为您的 YAML 语法不是指定数组的正确语法。 YAML 中的数组不应该是这样的吗?

database1:
  datasource:
    entity-packages: 
      - com.sample.database1.entities1
      - com.sample.database1.entities2

或者如果你想把它放在一行中,你可以使用 JSON 语法

database1:
  datasource:
    entity-packages: ['com.sample.database1.entities1', 'com.sample.database1.entities1']

更新

我找到了一个 blog post 正是关于您的问题。如果您想使用 YAML,您似乎需要使用 @ConfigurationProperties 而不是 @Value。 像这样使用.properties 而不是.yml 我没有任何问题:

database1.datasource.entity-packages=com.sample.database1.entities1, com.sample.database1.entities1

【讨论】:

  • 但是如何将这些值传递到需要数组的注释属性中?
  • 如果你使用application.properties而不是application.yml,你可以只保留你的java代码。出于某种原因,老实说我不明白,spring 抛出一个IllegalArgumentException 告诉我,当我使用 yml 语法时它无法解析占位符(就像我链接的博客文章中描述的那样)
【解决方案4】:

作为解决方法:

1) 将repository-package 属性赋值为com.sample.database1,因为它是这两个子包的公共包:com.sample.database1.repositories1,com.sample.database1.repositories2

那是:

database1:
   datasource:
      repository-package: com.sample.database1

2) 如果基础包并不总是相同,则采用其他方式。
basePackages 属性接受一个数组。所以用它来提供两个不同的元素:这是包的特定属性。

例如:

database1:
   datasource:
      repository-package-1: com.sample.database1.repositories1
      repository-package-2: com.sample.database1.repositories2

并使用它:

@Configuration
@EnableJpaRepositories(basePackages = 
            {"${database1.datasource.repository-package-1}", 
             "${database1.datasource.repository-package-2}"}, 
            ...
)
static class Database1DataSourceAutoConfiguration {

【讨论】:

  • 问题是我想概括@EnableJpaRepositories(basePackages =的内容。所以那里可能包含 1、2、n 个包。
猜你喜欢
  • 1970-01-01
  • 2018-09-25
  • 1970-01-01
  • 2022-01-20
  • 2017-06-14
  • 1970-01-01
  • 2018-01-21
  • 2018-12-04
  • 1970-01-01
相关资源
最近更新 更多