1 | package org.springframework.batch.core.repository.support; |
2 | |
3 | import org.springframework.aop.framework.ProxyFactory; |
4 | import org.springframework.aop.support.DefaultPointcutAdvisor; |
5 | import org.springframework.aop.support.NameMatchMethodPointcut; |
6 | import org.springframework.batch.core.repository.JobRepository; |
7 | import org.springframework.batch.core.repository.dao.JobExecutionDao; |
8 | import org.springframework.batch.core.repository.dao.JobInstanceDao; |
9 | import org.springframework.batch.core.repository.dao.StepExecutionDao; |
10 | import org.springframework.batch.support.PropertiesConverter; |
11 | import org.springframework.beans.factory.FactoryBean; |
12 | import org.springframework.beans.factory.InitializingBean; |
13 | import org.springframework.transaction.PlatformTransactionManager; |
14 | import org.springframework.transaction.interceptor.TransactionInterceptor; |
15 | import org.springframework.util.Assert; |
16 | |
17 | /** |
18 | * A {@link FactoryBean} that automates the creation of a |
19 | * {@link SimpleJobRepository}. Declares abstract methods for providing DAO |
20 | * object implementations. |
21 | * |
22 | * @see JobRepositoryFactoryBean |
23 | * @see MapJobRepositoryFactoryBean |
24 | * |
25 | * @author Ben Hale |
26 | * @author Lucas Ward |
27 | * @author Robert Kasanicky |
28 | */ |
29 | public abstract class AbstractJobRepositoryFactoryBean implements FactoryBean, InitializingBean { |
30 | |
31 | /** |
32 | * Default value for isolation level in create* method. |
33 | */ |
34 | private static final String DEFAULT_ISOLATION_LEVEL = "ISOLATION_SERIALIZABLE"; |
35 | |
36 | private ProxyFactory proxyFactory; |
37 | |
38 | private String isolationLevelForCreate = DEFAULT_ISOLATION_LEVEL; |
39 | |
40 | private PlatformTransactionManager transactionManager; |
41 | |
42 | /** |
43 | * @return fully configured {@link JobInstanceDao} implementation. |
44 | */ |
45 | protected abstract JobInstanceDao createJobInstanceDao() throws Exception; |
46 | |
47 | /** |
48 | * @return fully configured {@link JobExecutionDao} implementation. |
49 | */ |
50 | protected abstract JobExecutionDao createJobExecutionDao() throws Exception; |
51 | |
52 | /** |
53 | * @return fully configured {@link StepExecutionDao} implementation. |
54 | */ |
55 | protected abstract StepExecutionDao createStepExecutionDao() throws Exception; |
56 | |
57 | public Object getObject() throws Exception { |
58 | return proxyFactory.getProxy(); |
59 | } |
60 | |
61 | /** |
62 | * The type of object to be returned from {@link #getObject()}. |
63 | * |
64 | * @return JobRepository.class |
65 | * @see org.springframework.beans.factory.FactoryBean#getObjectType() |
66 | */ |
67 | public Class getObjectType() { |
68 | return JobRepository.class; |
69 | } |
70 | |
71 | public boolean isSingleton() { |
72 | return true; |
73 | } |
74 | |
75 | public void afterPropertiesSet() throws Exception { |
76 | |
77 | Assert.notNull(transactionManager, "TransactionManager must not be null."); |
78 | |
79 | initializeProxy(); |
80 | } |
81 | |
82 | protected void initializeProxy() throws Exception { |
83 | proxyFactory = new ProxyFactory(); |
84 | TransactionInterceptor advice = new TransactionInterceptor(transactionManager, PropertiesConverter |
85 | .stringToProperties("create*=PROPAGATION_REQUIRES_NEW," + isolationLevelForCreate |
86 | + "\n*=PROPAGATION_REQUIRED")); |
87 | DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor(advice); |
88 | NameMatchMethodPointcut pointcut = new NameMatchMethodPointcut(); |
89 | pointcut.addMethodName("*"); |
90 | advisor.setPointcut(pointcut); |
91 | proxyFactory.addAdvisor(advisor); |
92 | proxyFactory.setProxyTargetClass(false); |
93 | proxyFactory.addInterface(JobRepository.class); |
94 | proxyFactory.setTarget(getTarget()); |
95 | } |
96 | |
97 | private Object getTarget() throws Exception { |
98 | return new SimpleJobRepository(createJobInstanceDao(), createJobExecutionDao(), createStepExecutionDao()); |
99 | } |
100 | |
101 | /** |
102 | * Public setter for the {@link PlatformTransactionManager}. |
103 | * @param transactionManager the transactionManager to set |
104 | */ |
105 | public void setTransactionManager(PlatformTransactionManager transactionManager) { |
106 | this.transactionManager = transactionManager; |
107 | } |
108 | |
109 | /** |
110 | * Public setter for the isolation level to be used for the transaction when |
111 | * job execution entities are initially created. The default is |
112 | * ISOLATION_SERIALIZABLE, which prevents accidental concurrent execution of |
113 | * the same job (ISOLATION_REPEATABLE_READ would work as well). |
114 | * |
115 | * @param isolationLevelForCreate the isolation level name to set |
116 | * |
117 | * @see SimpleJobRepository#createJobExecution(org.springframework.batch.core.Job, |
118 | * org.springframework.batch.core.JobParameters) |
119 | */ |
120 | public void setIsolationLevelForCreate(String isolationLevelForCreate) { |
121 | this.isolationLevelForCreate = isolationLevelForCreate; |
122 | } |
123 | |
124 | } |