RESOLVED - BATCH-643: Create database type of 'map' in JobRepositoryFactoryBean

created separate factory bean for repository with map daos
This commit is contained in:
robokaso
2008-06-09 10:51:11 +00:00
parent 7a67464374
commit 9eb654c790
5 changed files with 218 additions and 100 deletions

View File

@@ -0,0 +1,124 @@
package org.springframework.batch.core.repository.support;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.aop.support.NameMatchMethodPointcut;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.repository.dao.JobExecutionDao;
import org.springframework.batch.core.repository.dao.JobInstanceDao;
import org.springframework.batch.core.repository.dao.StepExecutionDao;
import org.springframework.batch.support.PropertiesConverter;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.interceptor.TransactionInterceptor;
import org.springframework.util.Assert;
/**
* A {@link FactoryBean} that automates the creation of a
* {@link SimpleJobRepository}. Declares abstract methods for providing DAO
* object implementations.
*
* @see JobRepositoryFactoryBean
* @see MapJobRepositoryFactoryBean
*
* @author Ben Hale
* @author Lucas Ward
* @author Robert Kasanicky
*/
public abstract class AbstractJobRepositoryFactoryBean implements FactoryBean, InitializingBean {
/**
* Default value for isolation level in create* method.
*/
private static final String DEFAULT_ISOLATION_LEVEL = "ISOLATION_SERIALIZABLE";
private ProxyFactory proxyFactory;
private String isolationLevelForCreate = DEFAULT_ISOLATION_LEVEL;
private PlatformTransactionManager transactionManager;
/**
* @return fully configured {@link JobInstanceDao} implementation.
*/
protected abstract JobInstanceDao createJobInstanceDao() throws Exception;
/**
* @return fully configured {@link JobExecutionDao} implementation.
*/
protected abstract JobExecutionDao createJobExecutionDao() throws Exception;
/**
* @return fully configured {@link StepExecutionDao} implementation.
*/
protected abstract StepExecutionDao createStepExecutionDao() throws Exception;
public Object getObject() throws Exception {
return proxyFactory.getProxy();
}
/**
* The type of object to be returned from {@link #getObject()}.
*
* @return JobRepository.class
* @see org.springframework.beans.factory.FactoryBean#getObjectType()
*/
public Class getObjectType() {
return JobRepository.class;
}
public boolean isSingleton() {
return true;
}
public void afterPropertiesSet() throws Exception {
Assert.notNull(transactionManager, "TransactionManager must not be null.");
initializeProxy();
}
protected void initializeProxy() throws Exception {
proxyFactory = new ProxyFactory();
TransactionInterceptor advice = new TransactionInterceptor(transactionManager, PropertiesConverter
.stringToProperties("create*=PROPAGATION_REQUIRES_NEW," + isolationLevelForCreate
+ "\n*=PROPAGATION_REQUIRED"));
DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor(advice);
NameMatchMethodPointcut pointcut = new NameMatchMethodPointcut();
pointcut.addMethodName("*");
advisor.setPointcut(pointcut);
proxyFactory.addAdvisor(advisor);
proxyFactory.setProxyTargetClass(false);
proxyFactory.addInterface(JobRepository.class);
proxyFactory.setTarget(getTarget());
}
private Object getTarget() throws Exception {
return new SimpleJobRepository(createJobInstanceDao(), createJobExecutionDao(), createStepExecutionDao());
}
/**
* Public setter for the {@link PlatformTransactionManager}.
* @param transactionManager the transactionManager to set
*/
public void setTransactionManager(PlatformTransactionManager transactionManager) {
this.transactionManager = transactionManager;
}
/**
* Public setter for the isolation level to be used for the transaction when
* job execution entities are initially created. The default is
* ISOLATION_SERIALIZABLE, which prevents accidental concurrent execution of
* the same job (ISOLATION_REPEATABLE_READ would work as well).
*
* @param isolationLevelForCreate the isolation level name to set
*
* @see SimpleJobRepository#createJobExecution(org.springframework.batch.core.Job,
* org.springframework.batch.core.JobParameters)
*/
public void setIsolationLevelForCreate(String isolationLevelForCreate) {
this.isolationLevelForCreate = isolationLevelForCreate;
}
}

View File

@@ -18,10 +18,6 @@ package org.springframework.batch.core.repository.support;
import javax.sql.DataSource;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.aop.support.NameMatchMethodPointcut;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.repository.dao.AbstractJdbcBatchMetadataDao;
import org.springframework.batch.core.repository.dao.JdbcJobExecutionDao;
import org.springframework.batch.core.repository.dao.JdbcJobInstanceDao;
@@ -31,67 +27,33 @@ import org.springframework.batch.core.repository.dao.JobInstanceDao;
import org.springframework.batch.core.repository.dao.StepExecutionDao;
import org.springframework.batch.item.database.support.DataFieldMaxValueIncrementerFactory;
import org.springframework.batch.item.database.support.DefaultDataFieldMaxValueIncrementerFactory;
import org.springframework.batch.support.PropertiesConverter;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.jdbc.core.JdbcOperations;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.interceptor.TransactionInterceptor;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
* A {@link FactoryBean} that automates the creation of a
* {@link SimpleJobRepository}. Requires the user to describe what kind of
* {@link SimpleJobRepository} using JDBC DAO implementations which persist
* batch metadata in database. Requires the user to describe what kind of
* database they are using.
*
* @author Ben Hale
* @author Lucas Ward
*/
public class JobRepositoryFactoryBean implements FactoryBean, InitializingBean {
/**
* Default value for isolation level in create* method.
*/
private static final String DEFAULT_ISOLATION_LEVEL = "ISOLATION_SERIALIZABLE";
public class JobRepositoryFactoryBean extends AbstractJobRepositoryFactoryBean {
private DataSource dataSource;
private JdbcOperations jdbcTemplate;
private String databaseType;
private String tablePrefix = AbstractJdbcBatchMetadataDao.DEFAULT_TABLE_PREFIX;
private DataFieldMaxValueIncrementerFactory incrementerFactory;
private PlatformTransactionManager transactionManager;
private ProxyFactory proxyFactory;
private String isolationLevelForCreate = DEFAULT_ISOLATION_LEVEL;
/**
* Public setter for the {@link PlatformTransactionManager}.
* @param transactionManager the transactionManager to set
*/
public void setTransactionManager(PlatformTransactionManager transactionManager) {
this.transactionManager = transactionManager;
}
/**
* Public setter for the isolation level to be used for the transaction when
* job execution entities are initially created. The default is
* ISOLATION_SERIALIZABLE, which prevents accidental concurrent execution of
* the same job (ISOLATION_REPEATABLE_READ would work as well).
*
* @param isolationLevelForCreate the isolation level name to set
*
* @see SimpleJobRepository#createJobExecution(org.springframework.batch.core.Job,
* org.springframework.batch.core.JobParameters)
*/
public void setIsolationLevelForCreate(String isolationLevelForCreate) {
this.isolationLevelForCreate = isolationLevelForCreate;
}
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
@@ -109,8 +71,9 @@ public class JobRepositoryFactoryBean implements FactoryBean, InitializingBean {
}
public void afterPropertiesSet() throws Exception {
Assert.notNull(dataSource, "DataSource must not be null.");
Assert.notNull(transactionManager, "TransactionManager must not be null.");
jdbcTemplate = new JdbcTemplate(dataSource);
if (incrementerFactory == null) {
incrementerFactory = new DefaultDataFieldMaxValueIncrementerFactory(dataSource);
@@ -120,61 +83,10 @@ public class JobRepositoryFactoryBean implements FactoryBean, InitializingBean {
+ "' is an unsupported database type. The supported database types are "
+ StringUtils.arrayToCommaDelimitedString(incrementerFactory.getSupportedIncrementerTypes()));
initializeProxy();
super.afterPropertiesSet();
}
protected void initializeProxy() throws Exception {
proxyFactory = new ProxyFactory();
TransactionInterceptor advice = new TransactionInterceptor(transactionManager, PropertiesConverter
.stringToProperties("create*=PROPAGATION_REQUIRES_NEW," + isolationLevelForCreate
+ "\n*=PROPAGATION_REQUIRED"));
DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor(advice);
NameMatchMethodPointcut pointcut = new NameMatchMethodPointcut();
pointcut.addMethodName("*");
advisor.setPointcut(pointcut);
proxyFactory.addAdvisor(advisor);
proxyFactory.setProxyTargetClass(false);
proxyFactory.addInterface(JobRepository.class);
proxyFactory.setTarget(getTarget());
}
/**
* @return a SimpleJobRepository
*/
private SimpleJobRepository getTarget() throws Exception {
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
JobInstanceDao jobInstanceDao = createJobInstanceDao(jdbcTemplate);
JobExecutionDao jobExecutionDao = createJobExecutionDao(jdbcTemplate);
StepExecutionDao stepExecutionDao = createStepExecutionDao(jdbcTemplate);
return new SimpleJobRepository(jobInstanceDao, jobExecutionDao, stepExecutionDao);
}
/**
* Get a concrete {@link JobRepository}. The repository will be a proxy
* containing transaction advice using the supplied transaction manager.
*
* @return a {@link JobRepository}
* @see org.springframework.beans.factory.FactoryBean#getObject()
*/
public Object getObject() throws Exception {
return proxyFactory.getProxy();
}
/**
* The type of object to be returned from {@link #getObject()}.
*
* @return JobRepository.class
* @see org.springframework.beans.factory.FactoryBean#getObjectType()
*/
public Class getObjectType() {
return JobRepository.class;
}
public boolean isSingleton() {
return true;
}
private JobInstanceDao createJobInstanceDao(JdbcTemplate jdbcTemplate) throws Exception {
protected JobInstanceDao createJobInstanceDao() throws Exception {
JdbcJobInstanceDao dao = new JdbcJobInstanceDao();
dao.setJdbcTemplate(jdbcTemplate);
dao.setJobIncrementer(incrementerFactory.getIncrementer(databaseType, tablePrefix + "JOB_SEQ"));
@@ -183,7 +95,7 @@ public class JobRepositoryFactoryBean implements FactoryBean, InitializingBean {
return dao;
}
private JobExecutionDao createJobExecutionDao(JdbcTemplate jdbcTemplate) throws Exception {
protected JobExecutionDao createJobExecutionDao() throws Exception {
JdbcJobExecutionDao dao = new JdbcJobExecutionDao();
dao.setJdbcTemplate(jdbcTemplate);
dao.setJobExecutionIncrementer(incrementerFactory.getIncrementer(databaseType, tablePrefix
@@ -193,7 +105,7 @@ public class JobRepositoryFactoryBean implements FactoryBean, InitializingBean {
return dao;
}
private StepExecutionDao createStepExecutionDao(JdbcTemplate jdbcTemplate) throws Exception {
protected StepExecutionDao createStepExecutionDao() throws Exception {
JdbcStepExecutionDao dao = new JdbcStepExecutionDao();
dao.setJdbcTemplate(jdbcTemplate);
dao.setStepExecutionIncrementer(incrementerFactory.getIncrementer(databaseType, tablePrefix

View File

@@ -0,0 +1,32 @@
package org.springframework.batch.core.repository.support;
import org.springframework.batch.core.repository.dao.JobExecutionDao;
import org.springframework.batch.core.repository.dao.JobInstanceDao;
import org.springframework.batch.core.repository.dao.MapJobExecutionDao;
import org.springframework.batch.core.repository.dao.MapJobInstanceDao;
import org.springframework.batch.core.repository.dao.MapStepExecutionDao;
import org.springframework.batch.core.repository.dao.StepExecutionDao;
import org.springframework.beans.factory.FactoryBean;
/**
* A {@link FactoryBean} that automates the creation of a
* {@link SimpleJobRepository} using non-persistent in-memory DAO
* implementations.
*
* @author Robert Kasanicky
*/
public class MapJobRepositoryFactoryBean extends AbstractJobRepositoryFactoryBean {
protected JobExecutionDao createJobExecutionDao() throws Exception {
return new MapJobExecutionDao();
}
protected JobInstanceDao createJobInstanceDao() throws Exception {
return new MapJobInstanceDao();
}
protected StepExecutionDao createStepExecutionDao() throws Exception {
return new MapStepExecutionDao();
}
}