Reputation: 2921
We have a YML configuration which looks like:
datasurces:
readDataSource:
ssl-enabled: false
driver-class-name: oracle.jdbc.driver.OracleDriver
host: db1.abc.com
port: 1232
sid: ABC_DB
trust-store-fileName: abcdb.jks
connection-pool:
initial-size: 10
max-size: 20
writeDataSource:
ssl-enabled: false
driver-class-name: oracle.jdbc.driver.OracleDriver
host: db2.abc.com
port: 1232
sid: XYZ_DB
trust-store-fileName: xyzdb.jks
connection-pool:
initial-size: 10
max-size: 20
We have to load this to a custom class DataSources
which looks like
@ConfigurationProperties(prefix = "datasources")
public class DataSources {
@Value("${datasources.readDataSource}")
private DataSource readDataSource;
@Value("${datasources.writeDataSource}")
private DataSource writeDataSource;
//...getters/setters
}
public class DataSource {
private String id;
private boolean sslEnabled;
private String driverClassName;
private String host;
private int port;
private String trustStoreFileName;
private ConnectionPool connectionPool;
//...getters/setters
}
public class ConnectionPool {
private int initialSize;
private int maxSize;
//...getters/setters
}
My configuration files for spring boot looks like:
@Configuration
@ComponentScan(basePackages = {"com.abc"})
@EnableAspectJAutoProxy(proxyTargetClass = true)
@EnableConfigurationProperties(DataSources.class)
@Profile({"dev"})
public class TestAppConfiguration {
}
@EnableAutoConfiguration
@SpringBootApplication
@EnableConfigurationProperties(DataSources.class)
public class TestAppInitializer {
@Autowired
private DataSources dataSources;
public static void main(final String[] args) {
SpringApplication.run(TestAppInitializer.class, args);
}
}
The unit test is:
@SpringApplicationConfiguration(classes = {TestAppInitializer.class})
@Test(groups = "categoryTests")
@ActiveProfiles("dev")
public class DataSourcesTest extends AbstractTestNGSpringContextTests {
private static final AppLogger logger = LoggerUtil.getLogger(DataSourcesTest.class);
@Autowired
private DataSources dataSources;
@Test
public void printDetails() {
logger.debug("DataSources --> {}", dataSources);
}
}
Result is not as expected.
@Value
from DataSources
class, both the properties readDataSource
and writeDataSource
are null (The DataSources
class itself is not null).When I add @Value
in DataSources
class, the test fails with exception
Caused by: java.lang.IllegalStateException: Cannot convert value of type [java.lang.String] to required type [com.abc.DataSource]: no matching editors or conversion strategy found
Appreciate if someone can provide some idea how to deal with this. All I want is to capture both readDataSource
and writeDataSource
inside a class like DataSources
.
Upvotes: 0
Views: 6100
Reputation: 124431
Annotate your DataSources
class with @Configuration
then create 2 @Bean
methods annotatated with @ConfigurationProperties
.
@Configuration
public class DataSources {
@Bean
@ConfigurationProperties(prefix="datasources.readDataSource")
public DataSource readDataSource() {
return DataSourceBuilder.create().build();
}
@Bean
@ConfigurationProperties(prefix="datasources.writeDataSource")
public DataSource writeDataSource() {
return DataSourceBuilder.create().build();
}
}
Now you have 2 datasources with the properties bound to the created DataSource
s. This mechanism is explained here in the Spring Boot Reference Guide.
The same would apply if you don't need a DataSource
but construct your own object (although not sure why you would need that?).
Upvotes: 6