Andrew Wynham
Andrew Wynham

Reputation: 2398

Spring Configuration Metadata

I am setting up two data sources as shown here at http://docs.spring.io/spring-boot/docs/1.3.0.M2/reference/htmlsingle/#howto-two-datasources using spring boot, but when doing so my application.properties shows warnings that for example x.x.username is an unknown property. This is correct to some extent as javax.sql.DataSource does not contain url, username, password, etc. but the implementation classes do. I have annotation processor set up and it works fine when working with concrete classes.

I notice that org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration$NonEmbeddedConfiguration uses both DataSourceProperties and has @ConfigurationProperties annotated on dataSource(). This would probably get rid of my warnings but what is the point of this. Isn't it setting the properties twice this way?

Config:

@Bean
@Primary
@ConfigurationProperties(prefix="datasource.primary")
public DataSource primaryDataSource() {
    return DataSourceBuilder.create().build();
}

@Bean
@ConfigurationProperties(prefix="datasource.secondary")
public DataSource secondaryDataSource() {
    return DataSourceBuilder.create().build();
}

Properties with warnings:

datasource.primary.url=jdbc:...
datasource.primary.username=user
datasource.primary.password=password

datasource.secondary.url=jdbc:...
datasource.secondary.username=user
datasource.secondary.password=password

Upvotes: 4

Views: 2158

Answers (1)

Andrew Wynham
Andrew Wynham

Reputation: 2398

Since someone bothered to +1 this question I thought I'd post a solution. Note that I think the @ConfigurationProperties on the DataSources themselves are unecessary because they are already set on the DataSourceProperties which is used to build the DataSource, but I left it in there because that's how the Spring team has done it in org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration$NonEmbeddedConfiguration. My only guess why would be if your DataSource had additional properties that could be set other than what's exposed in DataSourceProperties, but then you would get warnings in the "Spring Boot application.properties editor" for those properties.

Note that DataSourceBuilder will use Tomcat, HikariCP or Commons DBCP in that order if found on Classpath as DataSource unless you specify something else with dataSourceBuilder.type(Class<? extends DataSource>)

Properties:

datasource.primary.url=jdbc:...
datasource.primary.username=user
datasource.primary.password=password

datasource.secondary.url=jdbc:...
datasource.secondary.username=user
datasource.secondary.password=password

Java Config:

@Bean
@Primary
@ConfigurationProperties(prefix = "datasource.primary")
public DataSourceProperties primaryProps() {
    return new DataSourceProperties();
}

@Bean
@ConfigurationProperties(prefix = "datasource.secondary")
public DataSourceProperties secondaryProps() {
    return new DataSourceProperties();
}

@Bean
@ConfigurationProperties(prefix = "datasource.primary")
public DataSource secondaryDataSource() {
    DataSourceProperties props = secondaryProps();
    return DataSourceBuilder.create(props.getClassLoader())
            .driverClassName(props.getDriverClassName())
            .url(props.getUrl())
            .username(props.getUsername())
            .password(props.getPassword())
            .build();
}

@Bean
@ConfigurationProperties(prefix = "datasource.primary")
public DataSource secondaryDataSource() {
    DataSourceProperties props = secondaryProps();
    return DataSourceBuilder.create(props.getClassLoader())
            .driverClassName(props.getDriverClassName())
            .url(props.getUrl())
            .username(props.getUsername())
            .password(props.getPassword())
            .build();
}

Upvotes: 1

Related Questions