spring - @Primary 即时
问题描述
我需要一个建议。
我有基础 Maven 项目,我在其中声明了所有存储库、实体和持久性类。它们都是无 XML 配置的。每个数据库及其所有相关类都按包划分。这个项目上的所有东西都被注释了,例如:@Entity、@Repository、@Configuration、@Primary 等等……它看起来像这样:
现在,radiusfttx.domain 包中的 bean 被注释为 @Primary。这个项目基本上就是它,它自己什么都不做。
然后,当我创建一个需要访问任何数据库的新项目时,我只需使用 Maven 导入第一个项目,并且在新项目初始化时,我像这样更改它(它是 Kotlin,但我很确定你可以得到想法):
@SpringBootApplication
@ComponentScan(basePackages = [
"com.entre.rest.boot", <-- my main class is here
"com.entre.databases.mailserver.domain", <-- repos from the other project
"com.entre.databases.integrator.domain" ])
由于所有内容都已注释,因此 Spring-boot 的自动配置会选择类并毫无问题地创建 bean。好吧,至少在我尝试向数据库提交一些东西之前。
因为只有一个持久性可以具有 @Primary 注释,所以如果我不将该持久性添加到 @ComponentScan 一切都不起作用。正如您在上面的示例中所看到的,我没有将“radiusfttx.domain”添加到@ComponentScan 并且@Primary 在那里。
所以我的问题是:有没有办法可以即时设置@Primary?被注释和硬编码不适用于我在这里尝试做的事情。有任何想法吗?
提前致谢。
编辑 1
作为一种解决方法,我创建了一个“虚拟”H2 持久性,我将其标记为 @Primary 并添加到我的所有项目中。这样,我所有的“真实”数据源都不需要设置@Primary。这远不是解决这种情况的方法,但它确实有效。如果有人能想出更好的东西,这个问题仍然悬而未决。
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(entityManagerFactoryRef = "emfDummy", transactionManagerRef = "tmDummy",
basePackages = ["com.entre.databases.dummy.domain"])
class DummyPersistence {
@Primary
@Bean("dsDummy")
fun dataSource() = HikariDataSource().apply {
username = "sa"
password = "sa"
jdbcUrl = "jdbc:h2:mem:db;DB_CLOSE_DELAY=-1"
driverClassName = "org.h2.Driver"
}
fun hibernateJpaVendorAdapter() = HibernateJpaVendorAdapter().apply {
setDatabasePlatform("org.hibernate.dialect.H2Dialect")
setShowSql(false)
setGenerateDdl(true)
}
@Primary
@Bean("emfDummy")
fun entityManagerFactory() = LocalContainerEntityManagerFactoryBean().apply {
setPackagesToScan("com.entre.databases.dummy.domain")
jpaVendorAdapter = hibernateJpaVendorAdapter()
dataSource = dataSource()
persistenceUnitName = "puDummy"
afterPropertiesSet()
}
@Primary
@Bean("tmDummy")
fun transactionManager() = JpaTransactionManager().apply {
entityManagerFactory = entityManagerFactory().`object`
}
}
解决方案
感谢所有的答案,你让我找到了正确的方向。
尽管我了解 @Qualifier 的使用,但对于我的特定项目来说还不够,因为据我所知,注释必须位于导入的“库”项目中。我的问题实际上出在事务上,因为在导入持久性配置尚未标记为@Primary 的特定包后,我无法指定@Primary。
所以这就是我解决它的方法。
我不仅在“库”项目上创建存储库,还在那里创建了@Service 层。这些@Services 我也可以用@Transactional 注释并命名事务管理器Spring 需要用于该特定服务。因此,例如,在“ServiceDummy”中,我可以添加 @Transactional("tmDummy") 并仅在其他应用程序上自动装配 @Service。这样一来,Spring 就不会争论有 2、3 或更多的事务管理器可供选择。
简要示例:
package com.entre.databases.dummy.service
@Service
@Transactional("tmDummy")
class DummyService(
val dummyRepository: DummyRepository)
{
fun findDummy(id: Int): Optional<Dummy> {
return dummyRepository.findById(id)
}
}
而在导入“库”的另一个应用程序上:
@SpringBootApplication
@ComponentScan(basePackages = [
"com.entre.rest.boot",
"com.entre.databases.dummy.service",
"com.entre.rest.web"
])
class Application
fun main(args: Array<String>) {
runApplication<Application>(*args)
}
推荐阅读
- python - Django 存根中断 Pycharm 自动完成
- mongodb - 如何在 GKE 服务的 MongoDB 中启用身份验证
- python - Count number of purchases a user has done on a pandas dataframe
- google-apps-script - 按字典顺序比较谷歌应用脚本中的字符串
- arrays - 使用 COUNTIFS 实现 HOUR
- google-apps-script - UrlFetchApp.fetch - 新的帖子限制截断发送的数据?
- pdf - 将 t1sasm C 程序编译成可执行文件
- javascript - jQuery Chosen Multiple Select
- java - 具有私有构造函数的 Java 子类产生编译错误
- amazon-web-services - 获取 AWS 用户的 MultiFactorAuthAge 的当前值