Spring 按前缀自动装配自定义 @ConfigurationProperties 对象

Spring autowire custom @ConfigurationProperties object by prefix

我想实现重要的 bean 注入实现。

我有一个自定义属性文件:

@Getter
@Setter
@ConfigurationProperties
public class DatabaseProperties {
  private String url;
  private String username;
  private String password;
}

我这里是配置文件:

@Configuration
@EnableConfigurationProperties(DatabaseProperties.class)
public class DBConfig {

  @Bean
  @ConfigurationProperties(prefix = "datasource.database1")
  public JdbcTemplate jdbcTemplateDatabase1(DatabaseProperties databaseProperties) {
    DataSource dataSource = new DriverManagerDataSource(
            databaseProperties.getUrl(),
            databaseProperties.getUsername(),
            databaseProperties.getPassword());
    return new JdbcTemplate(dataSource);
  }

  @Bean
  @ConfigurationProperties(prefix = "datasource.database2")
  public JdbcTemplate jdbcTemplateDatabase2(DatabaseProperties databaseProperties) {
    DataSource dataSource = new DriverManagerDataSource(
            databaseProperties.getUrl(),
            databaseProperties.getUsername(),
            databaseProperties.getPassword());
    return new JdbcTemplate(dataSource);
  }
}

我想实现的目标是根据前缀实例化一个新的DatabaseProperties实例。

有两种可能的解决方案:

但是是否可以摆脱为每个 JdbcTemplate 或使用 @Value 创建 DatabaseProperties bean?

据我所知,如果您想访问多个数据库,Spring 将无法为您施展魔法,这一事实是无法解决的。您将需要创建两个 JdbcTemplate Spring-managed bean,然后使用 @Qualifier 注释将它们注入到需要的地方。

这种方法有两个好处:

  1. 它确实有效;
  2. 你很清楚自己在做什么。一个 Spring 应用程序已经在其中发生了很多神奇的事情,所以当我们需要一些更自定义的东西并且实现起来并不复杂时,我们可能希望避免一些额外的事情。

您不需要创建 DatabaseProperties。 Spring 已经在数据源和属性变量上为我们做了这个


@Configuration
public class ConfigDataSource {


    @Bean("datasource-1")  // this name will qualify on @autowired
    @ConfigurationProperties(prefix="spring.datasource.yourname-datasource-1") // this is the name for the prefix for datasource on .properties settings
    public DataSource dataSourcePostgres() {
        return DataSourceBuilder.create().build();
    }
    
    
    @Bean("datasource-2")  // this name will qualify on @autowired
    @ConfigurationProperties(prefix="spring.datasource.yourname-datasource-2") // this is the name for the prefix for datasource on .properties settings
    public DataSource dataSourceMySql() {
        return DataSourceBuilder.create().build();
    }
    
}

.属性

# Its required use the same name declared in bean
spring.datasource.yourname-datasource-1.url=...
spring.datasource.yourname-datasource-1.jdbcUrl=${spring.datasource.yourname-datasource-1}
spring.datasource.yourname-datasource-1.username=user
spring.datasource.yourname-datasource-1.password=pass
spring.datasource.yourname-datasource-1.driver-class-name=your.driver

spring.datasource.yourname-datasource-2.url=...
spring.datasource.yourname-datasource-2.jdbcUrl=${spring.datasource.yourname-datasource-2}
spring.datasource.yourname-datasource-2.username=user
spring.datasource.yourname-datasource-2.password=pass
spring.datasource.yourname-datasource-2.driver-class-name=your.driver

在服务上使用


@Awtowired
@Qualifier("datasource-1")
private DataSource dataSource1;

@Awtowired
@Qualifier("datasource-2")
private DataSource dataSource2;

public testJdbcTemplate(){
     // You can qualifier JdbcTemplate below on bean and not necessary need instance on service
     JdbcTemplate jdbcTemplateDatasource1 = new JdbcTemplate(dataSource1);
     JdbcTemplate jdbcTemplateDatasource2 = new JdbcTemplate(dataSource2);
}