在 spring 批管理中读取外部属性文件
read external properties files in spring batch admin
前提:我是 spring 批次的新手。
我正在尝试自定义 spring 批处理管理,但是直到现在,我还不能让我的 classes 从外部文件读取一些属性。
我的作业从第三方数据库中提取数据以打印报告,因此我需要两个数据源:一个用于收集报告信息,一个用于存储作业的状态和元数据。
我已经阅读了教程:http://docs.spring.io/spring-batch-admin/reference/customization.html
and many other tutorials and the following post 。
但我无法启动该应用程序。
它必须 运行 在 Tomcat 6 上。
这是我的项目树的屏幕截图,由官方示例改编:
这是我的配置 class :
@Configuration
@EnableBatchProcessing
public class RegistroGiornalieroConfiguration extends DefaultBatchConfigurer {
private final static Logger log = LoggerFactory.getLogger(RegistroGiornalieroConfiguration.class);
private final static Date data = null;
@Autowired
public JobBuilderFactory jobFactory;
@Autowired
public StepBuilderFactory stepFactory;
@Autowired
VolumiPropertySource volumiPropertySource;
@Value("${batch.jdbc.driver}")
private String driverName;
/**
* datasource di default, viene resitituito dall'annotazione Autowired
* @return
* @throws SQLException
*/
@Bean(name="springBatchDatasource")
@Primary
public DataSource springBatchDatasource() throws SQLException {
final DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(driverName);//"com.mysql.jdbc.Driver");
// dataSource.setUrl(env.getProperty("springBatchUrl"));//"jdbc:mysql://localhost/spring_batch_annotations");
// dataSource.setUsername(env.getProperty("springBatchUser"));//"root");
// dataSource.setPassword(env.getProperty("springBatchPassword"));//"root");
return dataSource;
}
/**
* Datasource secondario, viene restituito da getDatasource
* @return
* @throws SQLException
*/
@Bean(name="estarDatasource")
public DataSource estarDatasource() throws SQLException {
final DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(driverName);//"com.mysql.jdbc.Driver");
// dataSource.setUrl(env.getProperty("url"));//"jdbc:mysql://localhost/spring_batch_annotations");
// dataSource.setUsername(env.getProperty("user"));//"root");
// dataSource.setPassword(env.getProperty("password"));//"root");
return dataSource;
}
// @PostConstruct
// public void init()
// {
// Properties p = volumiPropertySource.getIniProperties();
// MutablePropertySources sources = env.getPropertySources();
// sources.addFirst(new PropertiesPropertySource("volumi",p));
// env.getActiveProfiles();
// }
@Bean
@StepScope
public JdbcCursorItemReader<RegistroGiornaliero> reader(
@Value("#{jobParameters[data]}")
Date data)
{
System.out.println("reader");
// select protocol.nprotoc,protocol.dataprot,protocol.arrpar,protocol.numdoc,
// protocol.datadoc,protocol.OGGETTO,protocol.ANNULLATO,protocol.USERINS as protuser,
// protimg.DOCID,protimg.USERINS imguser ,protimg.PRINCIPALE,
// assegna.livello,assegna.possesso,assegna.SEQUENZA,
// organigramma.LIVELLO,organigramma.DESCRIZIONE,
// protente.ente
// from
// protocol left outer join protimg on protocol.NPROTOC = protimg.NPROTOC
// left outer join protente on protocol.NPROTOC = protente.NPROTOC
// left outer join assegna on protocol.NPROTOC = assegna.NPROTOC
// left outer join organigramma on assegna.LIVELLO = organigramma.LIVELLO
// where
// protocol.dataprot = 20160616 and protocol.NPROTOC = '201600014709'
// order by protocol.nprotoc,assegna.SEQUENZA;
StringBuilder sb = new StringBuilder("select")
.append(" protocol.nprotoc,protocol.dataprot,protocol.arrpar,protocol.numdoc,")
.append(" protocol.datadoc,protocol.OGGETTO,protocol.ANNULLATO,protocol.USERINS as protuser,")
.append(" protimg.DOCID,protimg.USERINS imguser ,protimg.PRINCIPALE,")
.append(" assegna.possesso,assegna.SEQUENZA,")
.append(" organigramma.LIVELLO,organigramma.DESCRIZIONE,")
.append(" protente.ente ")
.append(" from protocol left outer join protimg on protocol.NPROTOC = protimg.NPROTOC ")
.append(" left outer join protente on protocol.NPROTOC = protente.NPROTOC ")
.append(" left outer join assegna on protocol.NPROTOC = assegna.NPROTOC ")
.append(" left outer join organigramma on assegna.LIVELLO = organigramma.LIVELLO ")
.append(" where ")
.append(" protocol.dataprot = ? ")
.append(" order by protocol.nprotoc,assegna.SEQUENZA ");
// StringBuilder sb = new StringBuilder("select")
// .append(" protocol.nprotoc,protocol.dataprot,protocol.arrpar,protocol.numdoc,")
// .append(" protocol.datadoc,protocol.OGGETTO,protocol.ANNULLATO,protocol.USERINS as protuser, ")
// .append(" protimg.DOCID,protimg.USERINS imguser ,protimg.PRINCIPALE, ")
// .append(" assegna.livello,assegna.possesso,assegna.SEQUENZA, ")
// .append(" organigramma.LIVELLO as livelloOrg,organigramma.DESCRIZIONE, ")
// .append(" protente.ente ")
// .append(" from protocol,protimg,protente,assegna,operatori,organigramma ")
// .append(" where ")
// .append(" protocol.NPROTOC = protimg.NPROTOC and protocol.NPROTOC = assegna.NPROTOC ")
// .append(" and protocol.NPROTOC = protente.NPROTOC and assegna.LIVELLO = organigramma.LIVELLO ")
// .append(" and protocol.dataprot = ? ");
JdbcCursorItemReader<RegistroGiornaliero> reader = new JdbcCursorItemReader<RegistroGiornaliero>();
try {
reader.setDataSource(estarDatasource());
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
reader.setPreparedStatementSetter(new ParameterSetter(data));
reader.setSql(sb.toString());
reader.setRowMapper(estarRowMapper());
reader.setVerifyCursorPosition(false);
return reader;
}
@Bean
public RegistroGiornalieroProcessor processorGenerazioneRegistro() {
return new RegistroGiornalieroProcessor();
}
@Bean
public ItemWriter<RegistroGiornaliero> pdfwriter() {
return new PDFItemWriter<RegistroGiornaliero>();
}
@Bean
public JobExecutionListener listener() {
return new JobCompletionNotificationListener();
}
@Bean
public RegistroGiornalieroRowMapper estarRowMapper() {
return new RegistroGiornalieroRowMapper();
}
@Bean
public Job generaRegistroGiornaliero()
{
return jobFactory
.get("generaRegistroGiornaliero")
.incrementer(new RunIdIncrementer())
.flow(leggiDocumentiProtocollo())
.end()
.build();
}
@Bean
public Step leggiDocumentiProtocollo()
{
return stepFactory.get("leggiDocumentiProtocollo")
.<RegistroGiornaliero, RegistroGiornaliero> chunk(10)
.reader(reader(data))
.processor(processorGenerazioneRegistro())
.writer(pdfwriter())
.build();
}
@Override
public JobRepository getJobRepository() {
JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean();
// use the autowired data source
try {
factory.setDataSource(springBatchDatasource());
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
factory.setTransactionManager(getTransactionManager());
try {
factory.afterPropertiesSet();
return factory.getObject();
} catch (Exception e) {
// TODO Auto-generated catch block
//e.printStackTrace();
}
return null;
}
}
这是我的工作配置(registrogiornaliero.xml):
<?xml version="1.0" encoding="utf-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
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/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<context:annotation-config/>
<context:component-scan base-package="it.infogroup.estav.registrogiornaliero"/>
</beans>
最后这是我的 env.xml ,来自 Whosebug post :
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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.xsd">
<!-- Use this to set additional properties on beans at run time -->
<bean id="placeholderProperties"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:/org/springframework/batch/admin/bootstrap/batch.properties</value>
<value>classpath:batch-default.properties</value>
<!-- <value>classpath:batch-${ENVIRONMENT:hsql}.properties</value>-->
<value>classpath:batch-${ENVIRONMENT:mysql}.properties</value>
<!-- here we load properties from external config folder -->
<value>file:${app.conf}</value>
</list>
</property>
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
<property name="ignoreResourceNotFound" value="false" />
<property name="ignoreUnresolvablePlaceholders" value="false" />
<property name="order" value="1" />
</bean>
</beans>
任何帮助将不胜感激
免责声明:我是 spring 批处理的新手,因此这不是最佳解决方案:
我在我的配置 class 上使用了 propertysource 注释,我已经删除它并更改了 env-context.xml 如下所示:
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- Use this to set additional properties on beans at run time -->
<bean id="placeholderProperties"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:/org/springframework/batch/admin/bootstrap/batch.properties</value>
<value>${app.conf}/batch-default.properties</value>
<!-- <value>classpath:batch-${ENVIRONMENT:hsql}.properties</value>-->
<value>${app.conf}/batch-${ENVIRONMENT}.properties</value>
<!-- here we load properties from external config folder -->
<value>${app.conf}/estardatasource.properties</value>
</list>
</property>
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
<property name="ignoreResourceNotFound" value="false" />
<property name="ignoreUnresolvablePlaceholders" value="false" />
<property name="order" value="1" />
</bean>
${app.conf} 是一个 jvm 参数。
2. 我用占位符变量 es 替换了环境 class 的使用。 :
@Value("${volumi}")
private String volumi;
问题 2:多个数据源,有很多帖子描述了不同的解决方案,包括覆盖 DefaultBatchConfigurer class 及其 getJobRepository 方法。
唯一对我有用的解决方案是添加
@ComponentScan(basePackageClasses = DefaultBatchConfigurer.class)
配置 class,如 Use of multiple DataSources in Spring Batch
中所述(并清楚解释)
并覆盖数据源-context.xml 文件:我已将它放在 /src/main/resources/META-INF/spring/batch/override/ 下。
其内容是:
<?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:jdbc="http://www.springframework.org/schema/jdbc"
xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="estarDatasource" name="estarDatasource" primary="false"
class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${batch.jdbc.driver}" />
<property name="url" value="${url}" />
<property name="username" value="${user}" />
<property name="password" value="${password}" />
<property name="testWhileIdle" value="${batch.jdbc.testWhileIdle}"/>
<property name="validationQuery" value="${batch.jdbc.validationQuery}"/>
</bean>
<!-- Initialise the database if enabled: -->
<jdbc:initialize-database data-source="estarDatasource" enabled="${batch.data.source.init}" ignore-failures="DROPS">
<jdbc:script location="${batch.drop.script}"/>
<jdbc:script location="${batch.schema.script}"/>
<jdbc:script location="${batch.business.schema.script}"/>
</jdbc:initialize-database>
<bean id="dataSource" autowire-candidate="true" primary="true"
class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${batch.jdbc.driver}" />
<property name="url" value="${batch.jdbc.url}" />
<property name="username" value="${batch.jdbc.user}" />
<property name="password" value="${batch.jdbc.password}" />
<property name="testWhileIdle" value="${batch.jdbc.testWhileIdle}"/>
<property name="validationQuery" value="${batch.jdbc.validationQuery}"/>
</bean>
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<!-- Initialise the database if enabled: -->
<jdbc:initialize-database data-source="dataSource" enabled="${batch.data.source.init}" ignore-failures="DROPS">
<jdbc:script location="${batch.drop.script}"/>
<jdbc:script location="${batch.schema.script}"/>
<jdbc:script location="${batch.business.schema.script}"/>
</jdbc:initialize-database>
</beans>
希望这对其他初学者有所帮助,我很高兴知道这是否是一个合适的解决方案,以及最终如何将属性读入环境 class。
前提:我是 spring 批次的新手。
我正在尝试自定义 spring 批处理管理,但是直到现在,我还不能让我的 classes 从外部文件读取一些属性。
我的作业从第三方数据库中提取数据以打印报告,因此我需要两个数据源:一个用于收集报告信息,一个用于存储作业的状态和元数据。
我已经阅读了教程:http://docs.spring.io/spring-batch-admin/reference/customization.html
and many other tutorials and the following post
但我无法启动该应用程序。
它必须 运行 在 Tomcat 6 上。
这是我的项目树的屏幕截图,由官方示例改编:
这是我的配置 class :
@Configuration
@EnableBatchProcessing
public class RegistroGiornalieroConfiguration extends DefaultBatchConfigurer {
private final static Logger log = LoggerFactory.getLogger(RegistroGiornalieroConfiguration.class);
private final static Date data = null;
@Autowired
public JobBuilderFactory jobFactory;
@Autowired
public StepBuilderFactory stepFactory;
@Autowired
VolumiPropertySource volumiPropertySource;
@Value("${batch.jdbc.driver}")
private String driverName;
/**
* datasource di default, viene resitituito dall'annotazione Autowired
* @return
* @throws SQLException
*/
@Bean(name="springBatchDatasource")
@Primary
public DataSource springBatchDatasource() throws SQLException {
final DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(driverName);//"com.mysql.jdbc.Driver");
// dataSource.setUrl(env.getProperty("springBatchUrl"));//"jdbc:mysql://localhost/spring_batch_annotations");
// dataSource.setUsername(env.getProperty("springBatchUser"));//"root");
// dataSource.setPassword(env.getProperty("springBatchPassword"));//"root");
return dataSource;
}
/**
* Datasource secondario, viene restituito da getDatasource
* @return
* @throws SQLException
*/
@Bean(name="estarDatasource")
public DataSource estarDatasource() throws SQLException {
final DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(driverName);//"com.mysql.jdbc.Driver");
// dataSource.setUrl(env.getProperty("url"));//"jdbc:mysql://localhost/spring_batch_annotations");
// dataSource.setUsername(env.getProperty("user"));//"root");
// dataSource.setPassword(env.getProperty("password"));//"root");
return dataSource;
}
// @PostConstruct
// public void init()
// {
// Properties p = volumiPropertySource.getIniProperties();
// MutablePropertySources sources = env.getPropertySources();
// sources.addFirst(new PropertiesPropertySource("volumi",p));
// env.getActiveProfiles();
// }
@Bean
@StepScope
public JdbcCursorItemReader<RegistroGiornaliero> reader(
@Value("#{jobParameters[data]}")
Date data)
{
System.out.println("reader");
// select protocol.nprotoc,protocol.dataprot,protocol.arrpar,protocol.numdoc,
// protocol.datadoc,protocol.OGGETTO,protocol.ANNULLATO,protocol.USERINS as protuser,
// protimg.DOCID,protimg.USERINS imguser ,protimg.PRINCIPALE,
// assegna.livello,assegna.possesso,assegna.SEQUENZA,
// organigramma.LIVELLO,organigramma.DESCRIZIONE,
// protente.ente
// from
// protocol left outer join protimg on protocol.NPROTOC = protimg.NPROTOC
// left outer join protente on protocol.NPROTOC = protente.NPROTOC
// left outer join assegna on protocol.NPROTOC = assegna.NPROTOC
// left outer join organigramma on assegna.LIVELLO = organigramma.LIVELLO
// where
// protocol.dataprot = 20160616 and protocol.NPROTOC = '201600014709'
// order by protocol.nprotoc,assegna.SEQUENZA;
StringBuilder sb = new StringBuilder("select")
.append(" protocol.nprotoc,protocol.dataprot,protocol.arrpar,protocol.numdoc,")
.append(" protocol.datadoc,protocol.OGGETTO,protocol.ANNULLATO,protocol.USERINS as protuser,")
.append(" protimg.DOCID,protimg.USERINS imguser ,protimg.PRINCIPALE,")
.append(" assegna.possesso,assegna.SEQUENZA,")
.append(" organigramma.LIVELLO,organigramma.DESCRIZIONE,")
.append(" protente.ente ")
.append(" from protocol left outer join protimg on protocol.NPROTOC = protimg.NPROTOC ")
.append(" left outer join protente on protocol.NPROTOC = protente.NPROTOC ")
.append(" left outer join assegna on protocol.NPROTOC = assegna.NPROTOC ")
.append(" left outer join organigramma on assegna.LIVELLO = organigramma.LIVELLO ")
.append(" where ")
.append(" protocol.dataprot = ? ")
.append(" order by protocol.nprotoc,assegna.SEQUENZA ");
// StringBuilder sb = new StringBuilder("select")
// .append(" protocol.nprotoc,protocol.dataprot,protocol.arrpar,protocol.numdoc,")
// .append(" protocol.datadoc,protocol.OGGETTO,protocol.ANNULLATO,protocol.USERINS as protuser, ")
// .append(" protimg.DOCID,protimg.USERINS imguser ,protimg.PRINCIPALE, ")
// .append(" assegna.livello,assegna.possesso,assegna.SEQUENZA, ")
// .append(" organigramma.LIVELLO as livelloOrg,organigramma.DESCRIZIONE, ")
// .append(" protente.ente ")
// .append(" from protocol,protimg,protente,assegna,operatori,organigramma ")
// .append(" where ")
// .append(" protocol.NPROTOC = protimg.NPROTOC and protocol.NPROTOC = assegna.NPROTOC ")
// .append(" and protocol.NPROTOC = protente.NPROTOC and assegna.LIVELLO = organigramma.LIVELLO ")
// .append(" and protocol.dataprot = ? ");
JdbcCursorItemReader<RegistroGiornaliero> reader = new JdbcCursorItemReader<RegistroGiornaliero>();
try {
reader.setDataSource(estarDatasource());
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
reader.setPreparedStatementSetter(new ParameterSetter(data));
reader.setSql(sb.toString());
reader.setRowMapper(estarRowMapper());
reader.setVerifyCursorPosition(false);
return reader;
}
@Bean
public RegistroGiornalieroProcessor processorGenerazioneRegistro() {
return new RegistroGiornalieroProcessor();
}
@Bean
public ItemWriter<RegistroGiornaliero> pdfwriter() {
return new PDFItemWriter<RegistroGiornaliero>();
}
@Bean
public JobExecutionListener listener() {
return new JobCompletionNotificationListener();
}
@Bean
public RegistroGiornalieroRowMapper estarRowMapper() {
return new RegistroGiornalieroRowMapper();
}
@Bean
public Job generaRegistroGiornaliero()
{
return jobFactory
.get("generaRegistroGiornaliero")
.incrementer(new RunIdIncrementer())
.flow(leggiDocumentiProtocollo())
.end()
.build();
}
@Bean
public Step leggiDocumentiProtocollo()
{
return stepFactory.get("leggiDocumentiProtocollo")
.<RegistroGiornaliero, RegistroGiornaliero> chunk(10)
.reader(reader(data))
.processor(processorGenerazioneRegistro())
.writer(pdfwriter())
.build();
}
@Override
public JobRepository getJobRepository() {
JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean();
// use the autowired data source
try {
factory.setDataSource(springBatchDatasource());
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
factory.setTransactionManager(getTransactionManager());
try {
factory.afterPropertiesSet();
return factory.getObject();
} catch (Exception e) {
// TODO Auto-generated catch block
//e.printStackTrace();
}
return null;
}
}
这是我的工作配置(registrogiornaliero.xml):
<?xml version="1.0" encoding="utf-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
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/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<context:annotation-config/>
<context:component-scan base-package="it.infogroup.estav.registrogiornaliero"/>
</beans>
最后这是我的 env.xml ,来自 Whosebug post :
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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.xsd">
<!-- Use this to set additional properties on beans at run time -->
<bean id="placeholderProperties"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:/org/springframework/batch/admin/bootstrap/batch.properties</value>
<value>classpath:batch-default.properties</value>
<!-- <value>classpath:batch-${ENVIRONMENT:hsql}.properties</value>-->
<value>classpath:batch-${ENVIRONMENT:mysql}.properties</value>
<!-- here we load properties from external config folder -->
<value>file:${app.conf}</value>
</list>
</property>
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
<property name="ignoreResourceNotFound" value="false" />
<property name="ignoreUnresolvablePlaceholders" value="false" />
<property name="order" value="1" />
</bean>
</beans>
任何帮助将不胜感激
免责声明:我是 spring 批处理的新手,因此这不是最佳解决方案:
我在我的配置 class 上使用了 propertysource 注释,我已经删除它并更改了 env-context.xml 如下所示:
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- Use this to set additional properties on beans at run time --> <bean id="placeholderProperties" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations"> <list> <value>classpath:/org/springframework/batch/admin/bootstrap/batch.properties</value> <value>${app.conf}/batch-default.properties</value> <!-- <value>classpath:batch-${ENVIRONMENT:hsql}.properties</value>--> <value>${app.conf}/batch-${ENVIRONMENT}.properties</value> <!-- here we load properties from external config folder --> <value>${app.conf}/estardatasource.properties</value> </list> </property> <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" /> <property name="ignoreResourceNotFound" value="false" /> <property name="ignoreUnresolvablePlaceholders" value="false" /> <property name="order" value="1" /> </bean>
${app.conf} 是一个 jvm 参数。
2. 我用占位符变量 es 替换了环境 class 的使用。 :
@Value("${volumi}")
private String volumi;
问题 2:多个数据源,有很多帖子描述了不同的解决方案,包括覆盖 DefaultBatchConfigurer class 及其 getJobRepository 方法。
唯一对我有用的解决方案是添加
@ComponentScan(basePackageClasses = DefaultBatchConfigurer.class)
配置 class,如 Use of multiple DataSources in Spring Batch
中所述(并清楚解释)并覆盖数据源-context.xml 文件:我已将它放在 /src/main/resources/META-INF/spring/batch/override/ 下。
其内容是:
<?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:jdbc="http://www.springframework.org/schema/jdbc"
xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="estarDatasource" name="estarDatasource" primary="false"
class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${batch.jdbc.driver}" />
<property name="url" value="${url}" />
<property name="username" value="${user}" />
<property name="password" value="${password}" />
<property name="testWhileIdle" value="${batch.jdbc.testWhileIdle}"/>
<property name="validationQuery" value="${batch.jdbc.validationQuery}"/>
</bean>
<!-- Initialise the database if enabled: -->
<jdbc:initialize-database data-source="estarDatasource" enabled="${batch.data.source.init}" ignore-failures="DROPS">
<jdbc:script location="${batch.drop.script}"/>
<jdbc:script location="${batch.schema.script}"/>
<jdbc:script location="${batch.business.schema.script}"/>
</jdbc:initialize-database>
<bean id="dataSource" autowire-candidate="true" primary="true"
class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${batch.jdbc.driver}" />
<property name="url" value="${batch.jdbc.url}" />
<property name="username" value="${batch.jdbc.user}" />
<property name="password" value="${batch.jdbc.password}" />
<property name="testWhileIdle" value="${batch.jdbc.testWhileIdle}"/>
<property name="validationQuery" value="${batch.jdbc.validationQuery}"/>
</bean>
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<!-- Initialise the database if enabled: -->
<jdbc:initialize-database data-source="dataSource" enabled="${batch.data.source.init}" ignore-failures="DROPS">
<jdbc:script location="${batch.drop.script}"/>
<jdbc:script location="${batch.schema.script}"/>
<jdbc:script location="${batch.business.schema.script}"/>
</jdbc:initialize-database>
</beans>
希望这对其他初学者有所帮助,我很高兴知道这是否是一个合适的解决方案,以及最终如何将属性读入环境 class。