View Javadoc

1   /*
2    * Copyright 2012-2013 the original author or authors.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.springframework.batch.core.configuration.annotation;
17  
18  import java.lang.annotation.Documented;
19  import java.lang.annotation.ElementType;
20  import java.lang.annotation.Retention;
21  import java.lang.annotation.RetentionPolicy;
22  import java.lang.annotation.Target;
23  
24  import org.springframework.batch.core.configuration.JobRegistry;
25  import org.springframework.batch.core.configuration.support.ApplicationContextFactory;
26  import org.springframework.batch.core.configuration.support.AutomaticJobRegistrar;
27  import org.springframework.batch.core.launch.JobLauncher;
28  import org.springframework.batch.core.repository.JobRepository;
29  import org.springframework.context.annotation.Import;
30  import org.springframework.transaction.PlatformTransactionManager;
31  
32  /**
33   * <p>
34   * Enable Spring Batch features and provide a base configuration for setting up batch jobs in an &#064;Configuration
35   * class, roughly equivalent to using the {@code <batch:*>} XML namespace.
36   *
37   * <pre class="code">
38   * &#064;Configuration
39   * &#064;EnableBatchProcessing
40   * &#064;Import(DataSourceCnfiguration.class)
41   * public class AppConfig {
42   *
43   * 	&#064;Autowired
44   * 	private JobBuilderFactory jobs;
45   *
46   * 	&#064;Bean
47   * 	public Job job() {
48   * 		return jobs.get(&quot;myJob&quot;).start(step1()).next(step2()).build();
49   * 	}
50   *
51   * 	&#064;Bean
52   *    protected Step step1() {
53   *       ...
54   *    }
55   *
56   * 	&#064;Bean
57   *    protected Step step2() {
58   *     ...
59   *    }
60   * }
61   * </pre>
62   *
63   * The user has to provide a {@link DataSource} as a bean in the context, or else implement {@link BatchConfigurer} in
64   * the configuration class itself, e.g.
65   *
66   * <pre class="code">
67   * &#064;Configuration
68   * &#064;EnableBatchProcessing
69   * public class AppConfig extends DefaultBatchConfigurer {
70   *
71   *    &#064;Bean
72   *    public Job job() {
73   *       ...
74   *    }
75   *
76   *    &#064;Override
77   *    protected JobRepository createJobRepository() {
78   *       ...
79   *    }
80   *
81   *  ...
82   *
83   * }
84   * </pre>
85   *
86   * Note that only one of your configuration classes needs to have the <code>&#064;EnableBatchProcessing</code>
87   * annotation. Once you have an <code>&#064;EnableBatchProcessing</code> class in your configuration you will have an
88   * instance of {@link StepScope} so your beans inside steps can have <code>&#064;Scope("step")</code>. You will also be
89   * able to <code>&#064;Autowired</code> some useful stuff into your context:
90   *
91   * <ul>
92   * <li>a {@link JobRepository} (bean name "jobRepository")</li>
93   * <li>a {@link JobLauncher} (bean name "jobLauncher")</li>
94   * <li>a {@link JobRegistry} (bean name "jobRegistry")</li>
95   * <li>a {@link PlatformTransactionManager} (bean name "transactionManager")</li>
96   * <li>a {@link JobBuilderFactory} (bean name "jobBuilders") as a convenience to prevent you from having to inject the
97   * job repository into every job, as in the examples above</li>
98   * <li>a {@link StepBuilderFactory} (bean name "stepBuilders") as a convenience to prevent you from having to inject the
99   * job repository and transaction manager into every step</li>
100  * </ul>
101  *
102  * If the configuration is specified as <code>modular=true</code> then the context will also contain an
103  * {@link AutomaticJobRegistrar}. The job registrar is useful for modularizing your configuration if there are multiple
104  * jobs. It works by creating separate child application contexts containing job configurations and registering those
105  * jobs. The jobs can then create steps and other dependent components without needing to worry about bean definition
106  * name clashes. Beans of type {@link ApplicationContextFactory} will be registered automatically with the job
107  * registrar. Example:
108  *
109  * <pre class="code">
110  * &#064;Configuration
111  * &#064;EnableBatchProcessing(modular=true)
112  * public class AppConfig {
113  *
114  *    &#064;Bean
115  *    public ApplicationContextFactory someJobs() {
116  *       return new GenericApplicationContextFactory(SomeJobConfiguration.class);
117  *    }
118  *
119  *    &#064;Bean
120  *    public ApplicationContextFactory moreJobs() {
121  *       return new GenericApplicationContextFactory(MoreJobConfiguration.class);
122  *    }
123  *
124  *  ...
125  *
126  * }
127  * </pre>
128  *
129  * Note that a modular parent context in general should <em>not</em> itself contain &#64;Bean definitions for job,
130  * especially if a {@link BatchConfigurer} is provided, because cyclic configuration dependencies are otherwise likely
131  * to develop.
132  *
133  * </p>
134  *
135  * <p>
136  * For reference, the first example above can be compared to the following Spring XML configuration:
137  *
138  * <pre class="code">
139  * {@code
140  * <batch>
141  *     <job-repository />
142  *     <job id="myJob">
143  *       <step id="step1" .../>
144  *       <step id="step2" .../>
145  *     </job>
146  *     <beans:bean id="transactionManager" .../>
147  *     <beans:bean id="jobLauncher" class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
148  *       <beans:property name="jobRepository" ref="jobRepository" />
149  *     </beans:bean>
150  * </batch>
151  * }
152  * </pre>
153  *
154  * @author Dave Syer
155  *
156  */
157 @Target(ElementType.TYPE)
158 @Retention(RetentionPolicy.RUNTIME)
159 @Documented
160 @Import(BatchConfigurationSelector.class)
161 public @interface EnableBatchProcessing {
162 
163 	/**
164 	 * Indicate whether the configuration is going to be modularized into multiple application contexts. If true then
165 	 * you should not create any &#64;Bean Job definitions in this context, but rather supply them in separate (child)
166 	 * contexts through an {@link ApplicationContextFactory}.
167 	 */
168 	boolean modular() default false;
169 
170 }