/* * Copyright 2012-2014 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.batch.core.configuration.annotation; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import javax.sql.DataSource; import org.springframework.batch.core.configuration.JobRegistry; import org.springframework.batch.core.configuration.support.ApplicationContextFactory; import org.springframework.batch.core.configuration.support.AutomaticJobRegistrar; import org.springframework.batch.core.launch.JobLauncher; import org.springframework.batch.core.repository.JobRepository; import org.springframework.context.annotation.Import; import org.springframework.transaction.PlatformTransactionManager; /** * <p> * Enable Spring Batch features and provide a base configuration for setting up batch jobs in an @Configuration * class, roughly equivalent to using the {@code <batch:*>} XML namespace.</p> * * <pre class="code"> * @Configuration * @EnableBatchProcessing * @Import(DataSourceConfiguration.class) * public class AppConfig { * * @Autowired * private JobBuilderFactory jobs; * * @Bean * public Job job() { * return jobs.get("myJob").start(step1()).next(step2()).build(); * } * * @Bean * protected Step step1() { * ... * } * * @Bean * protected Step step2() { * ... * } * } * </pre> * * The user should to provide a {@link DataSource} as a bean in the context, or else implement {@link BatchConfigurer} in * the configuration class itself, e.g. * * <pre class="code"> * @Configuration * @EnableBatchProcessing * public class AppConfig extends DefaultBatchConfigurer { * * @Bean * public Job job() { * ... * } * * @Override * protected JobRepository createJobRepository() { * ... * } * * ... * * } * </pre> * * If a user does not provide a {@link javax.sql.DataSource} within the context, a Map based * {@link org.springframework.batch.core.repository.JobRepository} will be used. * * Note that only one of your configuration classes needs to have the <code>@EnableBatchProcessing</code> * annotation. Once you have an <code>@EnableBatchProcessing</code> class in your configuration you will have an * instance of {@link StepScope} and {@link org.springframework.batch.core.scope.JobScope} so your beans inside steps * can have <code>@Scope("step")</code> and <code>@Scope("job")</code> respectively. You will also be * able to <code>@Autowired</code> some useful stuff into your context: * * <ul> * <li>a {@link JobRepository} (bean name "jobRepository")</li> * <li>a {@link JobLauncher} (bean name "jobLauncher")</li> * <li>a {@link JobRegistry} (bean name "jobRegistry")</li> * <li>a {@link org.springframework.batch.core.launch.JobOperator} (bean name "jobOperator")</li> * <li>a {@link org.springframework.batch.core.explore.JobExplorer} (bean name "jobExplorer")</li> * <li>a {@link PlatformTransactionManager} (bean name "transactionManager")</li> * <li>a {@link JobBuilderFactory} (bean name "jobBuilders") as a convenience to prevent you from having to inject the * job repository into every job, as in the examples above</li> * <li>a {@link StepBuilderFactory} (bean name "stepBuilders") as a convenience to prevent you from having to inject the * job repository and transaction manager into every step</li> * </ul> * * If the configuration is specified as <code>modular=true</code> then the context will also contain an * {@link AutomaticJobRegistrar}. The job registrar is useful for modularizing your configuration if there are multiple * jobs. It works by creating separate child application contexts containing job configurations and registering those * jobs. The jobs can then create steps and other dependent components without needing to worry about bean definition * name clashes. Beans of type {@link ApplicationContextFactory} will be registered automatically with the job * registrar. Example: * * <pre class="code"> * @Configuration * @EnableBatchProcessing(modular=true) * public class AppConfig { * * @Bean * public ApplicationContextFactory someJobs() { * return new GenericApplicationContextFactory(SomeJobConfiguration.class); * } * * @Bean * public ApplicationContextFactory moreJobs() { * return new GenericApplicationContextFactory(MoreJobConfiguration.class); * } * * ... * * } * </pre> * * Note that a modular parent context in general should <em>not</em> itself contain @Bean definitions for job, * especially if a {@link BatchConfigurer} is provided, because cyclic configuration dependencies are otherwise likely * to develop. * * <p> * For reference, the first example above can be compared to the following Spring XML configuration: * * <pre class="code"> * {@code * <batch> * <job-repository /> * <job id="myJob"> * <step id="step1" .../> * <step id="step2" .../> * </job> * <beans:bean id="transactionManager" .../> * <beans:bean id="jobLauncher" class="org.springframework.batch.core.launch.support.SimpleJobLauncher"> * <beans:property name="jobRepository" ref="jobRepository" /> * </beans:bean> * </batch> * } * </pre> * * @author Dave Syer * */ @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Import(BatchConfigurationSelector.class) public @interface EnableBatchProcessing { /** * Indicate whether the configuration is going to be modularized into multiple application contexts. If true then * you should not create any @Bean Job definitions in this context, but rather supply them in separate (child) * contexts through an {@link ApplicationContextFactory}. */ boolean modular() default false; }