Spring Boot具有重复属性

时间:2015-12-17 15:38:35

标签: java spring spring-boot

我有一个设置我的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)

登台和生产环境必须同时使用两个数据源,因此登台有两个数据源(主要,辅助),生产有两个数据源(主要,辅助)。在主数据源和辅助数据源之间共享诸如驱动程序等设置。当尝试将这些公共属性注入第二个数据源时会出现问题。

2 个答案:

答案 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”)。

很高兴阅读: https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/context/annotation/Profile.html

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存储库中。