【发布时间】:2014-08-06 12:19:40
【问题描述】:
我有一个应用程序,它在 application.properties 中列出了许多数据源设置。我有一个 @ConfigurationProperties 类来加载这些设置。现在我想从这个ConfigurationProperties 类中获取值并使用它们即时创建DataSource bean。我试过使用@PostConstruct 并实现BeanFactoryPostProcessor。然而,对于BeanFactoryPostProcessor,处理似乎发生在早期——在我的ConfigurationProperties 类被填充之前。如何使用 Spring Boot 即时读取属性并创建 DataSource bean?
这是我的 application.properties 的样子:
ds.clients[0]=client1|jdbc:db2://server/client1
ds.clients[1]=client2,client3|jdbc:db2://server/client2
ds.clients[2]=client4|jdbc:db2://server/client4
ds.clients[3]=client5|jdbc:db2://server/client5
还有我的 ConfigurationProperties 类:
@Component
@ConfigurationProperties(prefix = "ds")
public class DataSourceSettings {
public static Map<String, String> CLIENT_DATASOURCES = new LinkedHashMap<>();
private List<String> clients = new ArrayList<>();
public List<String> getClients() {
return clients;
}
public void setClients(List<String> clients) {
this.clients = clients;
}
@PostConstruct
public void configure() {
for (String client : clients) {
// extract client name
String[] parts = client.split("\\|");
String clientName = parts[0];
String url = parts[1];
// client to datasource mapping
String dsName = url.substring(url.lastIndexOf("/") + 1);
if (clientName.contains(",")) {
// multiple clients with same datasource
String[] clientList = clientName.split(",");
for (String c : clientList) {
CLIENT_DATASOURCES.put(c, dsName);
}
} else {
CLIENT_DATASOURCES.put(clientName, dsName);
}
}
}
在这个@PostConstruct 方法的最后,我想用这些设置创建一个BasicDataSource 并将它添加到ApplicationContext。但是,如果我尝试通过实现 BeanFactoryPostProcessor 并实现 postProcessBeanFactory 来实现此目的,则 clients 属性为空,我使用 @PostConstruct 填充的 CLIENT_DATASOURCES 也是如此。
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("clients: " + CLIENT_DATASOURCES);
}
使用 Spring Boot 即时创建数据源的最佳方式是什么?
【问题讨论】:
-
这是一个老问题,所以值得old answer。它不是特定于 Spring Boot,而是通用于 Spring。我认为它仍然成立。
标签: java spring spring-boot