我有一个应用程序,其中包含application.properties中列出的许多数据源设置 . 我有一个加载这些设置的 @ConfigurationProperties
类 . 现在我想从这个 ConfigurationProperties
类获取值,并使用它们即时创建DataSource bean . 我尝试过使用 @PostConstruct
并实现 BeanFactoryPostProcessor
. 但是,使用 BeanFactoryPostProcessor
,处理似乎很早就发生了 - 在我的 ConfigurationProperties
类已经填充之前 . 如何使用Spring Boot快速读取属性并创建 DataSource
beans?
这是我的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
属性为null,因为我填充了 @PostConstruct
的 CLIENT_DATASOURCES
.
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("clients: " + CLIENT_DATASOURCES);
}
使用Spring Boot动态创建数据源的最佳方法是什么?
2 回答
如何创建bean并请求Boot向其中注入值?
就像是
然后,
ds.client1
命名空间中的任何设置都属于第一个数据源(即ds.client1.password
是该DataSource
的数据源密码) .但也许您不知道您将拥有多少数据源?这变得越来越复杂,特别是如果您需要在其他对象中注入这些动态数据源 . 如果您只需要按名称查找它们,您可以将它们自己注册为单身 . 这是一个有效的例子
请注意,通过bean名称查找可以使用这些bean only . 如果这对您有用,请告诉我 .
我在github上创建了一个示例项目来演示你的用例 .
https://github.com/lhotari/dynamic-datasources
我实现了ImportBeanDefinitionRegistrar来添加bean . 您可以通过实现EnvironmentAware来获取配置 . 可能还有其他方法可以实现您的目标,但这是我在GspAutoConfiguration中用于动态注册bean的方式 . GspAutoConfiguration使Grails GSP可用于Spring Boot应用程序 .
这是dynamic-datasource示例中的相关配置类:https://github.com/lhotari/dynamic-datasources/blob/master/src/main/groovy/sample/DynamicDataSourcesConfiguration.java