我有一个设置我的spring web应用程序,其中有两个数据源,主要数据源和次要数据源。这两个数据源主要共享除用户名,密码和URL之外的所有配置属性。随着公共属性列表的增长,我希望对两个数据源使用公共配置属性,并仅指定要为辅助数据源和其他数据源覆盖哪些属性。例如,我已经设置了我的主数据源bean:
@Bean
@Primary
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource dataSource() {
return DataSourceBuilder.create().build();
}
在辅助数据源中:
@Value("${spring.secondaryDatasource.url}")
private String databaseUrl;
@Value("${spring.datasource.username}")
private String username;
@Value("${spring.datasource.password}")
private String password;
@Value("${spring.datasource.driver-class-name}")
private String driver;
@Bean
public DataSource secondaryDataSource() {
return DataSourceBuilder
.create()
.url(databaseUrl)
.username(username)
.password(password)
.driverClassName(driver)
.build();
}
我还设置了一个类似于我当前设置的示例项目: https://github.com/Edvinas01/MultipleDatasources
是否可以在仅指定要覆盖的属性的同时注入重复属性(如驱动程序名称等)?这样的事情(这不起作用):
@Bean
@ConfigurationProperties(prefix = "spring.datasource") // Inject default properties
public DataSource secondaryDataSource() {
return DataSourceBuilder
.create()
.url(databaseUrl) // Override url
.username(username) // Override username
.password(password) // Override password
.build();
}
修改
我已将.properties文件替换为.yml配置文件,如下所示:
spring:
jpa.hibernate.ddl-auto: update
datasource:
username: main
password: main
url: jdbc:hsqldb:mem:main
driver-class-name: org.hsqldb.jdbc.JDBCDriver
---
spring:
profiles: secondary
datasource:
username: secondary
password: secondary
url: jdbc:hsqldb:mem:secondary
---
spring:
profiles.active: default,secondary
数据源bean:
@Bean
@Primary
@Profile("default")
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource dataSource() {
return DataSourceBuilder.create().build();
}
@Bean
@Profile({"secondary", "default"})
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource secondaryDataSource() {
return DataSourceBuilder.create().build();
}
我的主数据源(默认)获取辅助数据源值,但辅助配置文件配置中未指定的驱动程序除外。辅助数据源获取正确的属性。
是否有可能的解决方案,不使用.yml格式进行配置或不必为每个配置文件创建多个.applications文件?
EDIT2: 一些澄清,在我们的设置中,我们有当前的属性文件:
application.properties (sets the active profile according to the machine and common properties)
application-stating.properties (staging machine)
application-production.properties (production machine)
登台和生产环境必须同时使用两个数据源,因此登台有两个数据源(主要,辅助),生产有两个数据源(主要,辅助)。在主数据源和辅助数据源之间共享诸如驱动程序等设置。当尝试将这些公共属性注入第二个数据源时会出现问题。
答案 0 :(得分:1)
我建议将Spring配置文件与YAML配置结合使用(如果可能,但它可以适应属性文件)。
// Insert in your Spring Configuration Class
@Profile("!production")
@ConfigurationProperties(prefix = "spring.datasource")
@Bean
public DataSource dataSource() {
return DataSourceBuilder.create().build();
}
@Profile("production")
@ConfigurationProperties(prefix = "spring.datasource")
@Bean
public DataSource secondDataSource() {
return DataSourceBuilder
.create()
.url(databaseUrl) // Override url
.username(username) // Override username
.password(password) // Override password
.build();
}
如果您使用适当的个人资料启动您的申请,例如第二个(参见http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-profiles.html),然后加载正确的DataSource。默认配置文件不需要设置spring.profiles.active
值。
编辑:
无需创建其他配置文件或文件。 提醒:您可以通过-Dspring.profiles.active="production"
设置默认配置文件。如果没有设置默认配置文件,那么它是default
,您不必创建/定义。
好的,回到主题:
假设您希望使用“生产”和“暂存”配置文件,并为每个配置文件激活一个配置。
您可以通过替换@Profile("default")
来完成上述经典操作
第一个bean中的@Profile("default", "production")
。
在第二个bean中,将@Profile("second")
替换为@Profile("staging")
。
另一种方法是通过逻辑运算符来完成。
对于“生产”配置文件,您希望使用用户名/密码数据源。
所以这里需要一个@Profile("production")
注释。
对于非生产性用法(在您的情况下为staging
),您可以使用@Profile(“!production”)。
EDIT2:
对于具有一个属性/ YAML文件的解决方案,我将采用以下方法:
# application.yml
# default settings
spring:
datasource:
# insert your default settings
---
spring:
profiles: staging
datasource:
# insert staging settings here
---
spring:
profiles: production
datasource:
# insert production settings here
这为每个配置文件保存了其他属性文件。
答案 1 :(得分:1)
最后,我们使用了两个数据源的可重用属性。首先,我创建了一个bean来存储这些常见属性:
@Configuration
public class CommonPropertiesConfiguration {
@Bean
@ConfigurationProperties(prefix = "spring.datasource")
public PoolProperties poolProperties() {
return new PoolProperties();
}
}
在第二个数据源配置中,我自动装配公共属性(所有数据源属性)并按值注入此数据源的特定属性:
@Value("${spring.secondaryDatasource.username}")
private String username;
@Value("${spring.secondaryDatasource.password}")
private String password;
@Value("${spring.secondaryDatasource.url}")
private String url;
@Autowired
private PoolProperties poolProperties;
@Bean
public DataSource secondaryDataSource() {
DataSource dataSource = new DataSource(poolProperties);
dataSource.setPassword(password);
dataSource.setUsername(username);
dataSource.setUrl(url);
return dataSource;
}
现在application.properties看起来像这样:
# Main/common data source properties.
spring.datasource.username=test
spring.datasource.password=test
spring.datasource.url=jdbc:hsqldb:mem:main
spring.datasource.driver-class-name=org.hsqldb.jdbc.JDBCDriver
# Override these properties for second datasource.
spring.secondaryDatasource.username=second
spring.secondaryDatasource.password=second
spring.secondaryDatasource.url=jdbc:hsqldb:mem:secondary
logging.level.com.datasources=DEBUG
spring.jpa.hibernate.ddl-auto=update
更改也会反映在github存储库中。