我在几个应用程序中有以下配置的db-config.xml文件。我们正在使用Spring Batch,每个应用程序都从几个外部数据库中获取数据。一切都运行良好,但问题是所有应用程序都部署在不同的服务器上,每当密码到期“其中一个”数据源“时,我们必须在每个服务器上运行并在db-config文件上手动更改密码对于每个申请。
由于所有应用程序使用或多或少相同的数据源进行收获(总共约9个),我目前正在寻找一些替代方案,而不是将“Harvest Data sources”声明为db-config.xml文件将所有属性放入数据库表并从那里加载属性。当密码到期时,我们在一个地方而不是x个地方进行更改。
我真的很感激任何正确的指示只是为了开始...
我的db-config.xml示例
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.ibm.db2.jcc.DB2Driver"></property>
<property name="url" value="jdbc:db2://1.111.1.11:50000/EX1"></property>
<property name="username" value="xxxxx" />
<property name="password" value="xxxxx" />
</bean>
<bean class="com.mchange.v2.c3p0.ComboPooledDataSource" id="ef_DataSource">
<property name="driverClass" value="com.ibm.db2.jcc.DB2Driver"></property>
<property name="acquireIncrement" value="5"></property>
<property name="maxIdleTime" value="3600"></property>
<property name="maxPoolSize" value="15"></property>
<property name="minPoolSize" value="5"></property>
<property name="numHelperThreads" value="3"></property>
<property name="unreturnedConnectionTimeout" value="3600"></property>
<property name="idleConnectionTestPeriod" value="100"></property>
<property name="jdbcUrl" value="jdbc:db2://2.222.2.22:50000/EX2"></property>
<property name="user" value="xxxxx" />
<property name="password" value="xxxxxx" />
</bean>
<!-- Harvest Data sources -->
<bean class="org.springframework.jdbc.datasource.DriverManagerDataSource" id="rep1">
<property name="driverClassName" value="com.ibm.db2.jcc.DB2Driver"></property>
<property name="url" value="jdbc:db2://1.11.11.111:60000/REPONE"></property>
<property name="username" value="xxxxxxxx" />
<property name="password" value="xxxxxxxx" />
</bean>
<bean class="org.springframework.jdbc.datasource.DriverManagerDataSource" id="rep4">
<property name="driverClassName" value="com.ibm.db2.jcc.DB2Driver"></property>
<property name="url" value="jdbc:db2://22.444.44.44:50000/REPTWO"></property>
<property name="username" value="xxxxxxxx"></property>
<property name="password" value="xxxxxxxx"></property>
</bean>
<bean class="org.springframework.jdbc.datasource.DriverManagerDataSource" id="rep5">
<property name="driverClassName" value="com.ibm.db2.jcc.DB2Driver"></property>
<property name="url" value="jdbc:db2://555.55.55.55:50000/REPTHREE"></property>
<property name="username" value="xxxxxxxx" />
<property name="password" value="xxxxxxxx" />
</bean>
<!-- More Harvest Data sources -->
所有Tasklets类扩展的AbstractImportTasklet java类示例
@Component
public abstract class AbstractImportTasklet implements ResourceLoaderAware, InitializingBean, Tasklet{
private ResourceLoader resourceLoader;
private JdbcTemplate jdbcTemplate;
private NamedParameterJdbcTemplate namedParameterJdbcTemplate;
private DataSource dataSource;
@Autowired
AmDbDAO dao;
@Autowired
protected JobExplorer jobExplorer;
public AbstractImportTasklet() {
super();
}
@Override
public void setResourceLoader(ResourceLoader resourceLoader) {
this.resourceLoader = resourceLoader;
}
public JdbcTemplate getJdbcTemplate() {
return jdbcTemplate;
}
public NamedParameterJdbcTemplate getNamedParameterJdbcTemplate(){
return namedParameterJdbcTemplate;
}
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
public void setNamedParameterJdbcTemplate(NamedParameterJdbcTemplate namedParameterJdbcTemplate){
this.namedParameterJdbcTemplate = namedParameterJdbcTemplate;
}
public DataSource getDataSource() {
return dataSource;
}
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
@Override
public void afterPropertiesSet() throws Exception {
/*TimeZone.setDefault(TimeZone.getTimeZone("UTC"));*/
if(dataSource != null){
this.jdbcTemplate = new JdbcTemplate(dataSource);
this.namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
}
}
}
答案 0 :(得分:0)
可能的方法之一是在开头添加一个步骤,读取包含其他信息的数据库(如果我正确理解您的用例)。然后,此步骤将结果加载到JobExecutionContext
中。结果将用于数据源的定义。
这是一个例子(步骤):
public class LoadDatasources implements Tasklet {
public RepeatStatus execute(StepContribution stepContribution, ChunkContext chunkContext) throws Exception {
// Query database here
[...]
// Save results in context
chunkContext.getStepContext().getJobExecutionContext().put(key, value)
return null;
}
}
数据源的XML配置:
<bean class="org.springframework.jdbc.datasource.DriverManagerDataSource" step="scope">
<property name="driverClassName" value="#{jobExecutionContext['datasource1.driver']}"></property>
<property name="url" value="#{jobExecutionContext['datasource1.url']}"></property>
<property name="username" value="#{jobExecutionContext['datasource1.username']}"></property>
<property name="password" value="#{jobExecutionContext['datasource1.password']}"></property>
</bean>
答案 1 :(得分:0)
这是Spring Cloud的Configuration Server解决的确切用例。它允许您在中央存储库中配置数据源等内容。从那里,您可以使用它刷新应用程序的配置。您可以在此处的文档中阅读有关Spring Cloud Configuration Server的更多信息:https://github.com/spring-cloud-samples/configserver