gpt4 book ai didi

java - 运行时 Spring : How to manage datasources created with BeanFactoryPostProcessor,?

转载 作者:行者123 更新时间:2023-11-29 14:03:10 24 4
gpt4 key购买 nike

我正在使用 Spring Data JPA 开发一个项目。

我已经设法使用 BeanFactoryPostProcessor 动态创建数据源,并在使用 AbstractRoutingDataSource 登录时切换到所需的数据源。

现在我想在运行时做的是:

  1. 获取动态数据源的映射BeanFactory后处理器
  2. 创建一个新的数据源
  3. 将最近创建的数据源与其他数据源一起放入 map 中

springContext-jpa.xml

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
............
>
<!--
...
...
Spring Data JPA config
...
...
-->

<!-- Parent abstract Datasource -->
<bean id="BasicdsCargestWeb" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>

<!-- Generic Datasource -->
<bean id="dsCargestWeb" class="com.cargest.custom.CargestRoutingDataSource">
<property name="targetDataSources">
<map>

</map>
</property>
<property name="defaultTargetDataSource" ref="cargestnet1ds" />
</bean>

</beans>

DatasourceRegisteringBeanFactoryPostProcessor.java

@Component 
class DatasourceRegisteringBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {

// this is my list of Datasources
List<Database> dbs = new ArrayList<Database>();

/*
* Hidden code, here i get my list of Datasources
*/

BeanDefinitionRegistry factory = (BeanDefinitionRegistry) beanFactory;
BeanDefinitionBuilder datasourceDefinitionBuilder;

for (Database db : dbs) {
datasourceDefinitionBuilder = BeanDefinitionBuilder
.childBeanDefinition("BasicdsCargestWeb")
.addPropertyValue("url", db.getUrl()+db.getName()+"?autoReconnect=true");

factory.registerBeanDefinition("cargestnet"+db.getId()+"ds",
datasourceDefinitionBuilder.getBeanDefinition());
}


// Configure the dataSource bean properties
MutablePropertyValues mpv = factory.getBeanDefinition("dsCargestWeb").getPropertyValues();

// Here you can set the default dataSource
mpv.removePropertyValue("defaultTargetDataSource");
mpv.addPropertyValue("defaultTargetDataSource",
new RuntimeBeanReference("cargestnet1ds"));

// Set the targetDataSource properties map with the list of connections
ManagedMap<String, RuntimeBeanReference> mm = (ManagedMap<String, RuntimeBeanReference>) mpv.getPropertyValue("targetDataSources").getValue();
System.out.println("list size "+mm.size());

mm.clear();

for (Database db : dbs) {
mm.put(db.getId().toString(), new RuntimeBeanReference("cargestnet"+db.getId()+"ds"));
}
}
}

问题是 BeanFactoryPostProcessor 类正在使用 ConfigurableListableBeanFactory 作为 beanFactory。

我需要从另一个类(在运行时)访问同一个 beanFactory,以便修改我的数据源映射(dsCargestWeb --> targetDataSources --> 映射)。

谢谢

最佳答案

我认为您可以尝试以下架构:

  • 工厂 bean 创建 DataSourceS 的初始映射
  • AbstractRoutingDataSource 实现持有 DataSourceS 的映射,并且最初注入(inject)上述工厂 bean

那样的话,如果您以后需要添加一个新的DataSource,您可以从AbstractRoutingDataSource 实现中获取 map 并将其直接添加到其中,或者将一个AbstractRoutingDataSource 实现中的方法添加一个新的 DataSource

作为上述的变体,您可以创建一个类似的 AbstractRoutingDataSource 实现,并注入(inject)另一个 bean,在其 init-method 中计算 DataSourceS映射并存储在路由数据源中。

关于java - 运行时 Spring : How to manage datasources created with BeanFactoryPostProcessor,?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26296896/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com