/* * Copyright 2002-2016 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.transaction.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 org.springframework.context.annotation.AdviceMode; import org.springframework.context.annotation.Import; import org.springframework.core.Ordered; /** * Enables Spring's annotation-driven transaction management capability, similar to * the support found in Spring's {@code <tx:*>} XML namespace. To be used on * {@link org.springframework.context.annotation.Configuration @Configuration} * classes as follows: * * <pre class="code"> * @Configuration * @EnableTransactionManagement * public class AppConfig { * * @Bean * public FooRepository fooRepository() { * // configure and return a class having @Transactional methods * return new JdbcFooRepository(dataSource()); * } * * @Bean * public DataSource dataSource() { * // configure and return the necessary JDBC DataSource * } * * @Bean * public PlatformTransactionManager txManager() { * return new DataSourceTransactionManager(dataSource()); * } * }</pre> * * <p>For reference, the example above can be compared to the following Spring XML * configuration: * * <pre class="code"> * {@code * <beans> * * <tx:annotation-driven/> * * <bean id="fooRepository" class="com.foo.JdbcFooRepository"> * <constructor-arg ref="dataSource"/> * </bean> * * <bean id="dataSource" class="com.vendor.VendorDataSource"/> * * <bean id="transactionManager" class="org.sfwk...DataSourceTransactionManager"> * <constructor-arg ref="dataSource"/> * </bean> * * </beans> * }</pre> * * In both of the scenarios above, {@code @EnableTransactionManagement} and {@code * <tx:annotation-driven/>} are responsible for registering the necessary Spring * components that power annotation-driven transaction management, such as the * TransactionInterceptor and the proxy- or AspectJ-based advice that weave the * interceptor into the call stack when {@code JdbcFooRepository}'s {@code @Transactional} * methods are invoked. * * <p>A minor difference between the two examples lies in the naming of the {@code * PlatformTransactionManager} bean: In the {@code @Bean} case, the name is * <em>"txManager"</em> (per the name of the method); in the XML case, the name is * <em>"transactionManager"</em>. The {@code <tx:annotation-driven/>} is hard-wired to * look for a bean named "transactionManager" by default, however * {@code @EnableTransactionManagement} is more flexible; it will fall back to a by-type * lookup for any {@code PlatformTransactionManager} bean in the container. Thus the name * can be "txManager", "transactionManager", or "tm": it simply does not matter. * * <p>For those that wish to establish a more direct relationship between * {@code @EnableTransactionManagement} and the exact transaction manager bean to be used, * the {@link TransactionManagementConfigurer} callback interface may be implemented - * notice the {@code implements} clause and the {@code @Override}-annotated method below: * * <pre class="code"> * @Configuration * @EnableTransactionManagement * public class AppConfig implements TransactionManagementConfigurer { * * @Bean * public FooRepository fooRepository() { * // configure and return a class having @Transactional methods * return new JdbcFooRepository(dataSource()); * } * * @Bean * public DataSource dataSource() { * // configure and return the necessary JDBC DataSource * } * * @Bean * public PlatformTransactionManager txManager() { * return new DataSourceTransactionManager(dataSource()); * } * * @Override * public PlatformTransactionManager annotationDrivenTransactionManager() { * return txManager(); * } * }</pre> * * This approach may be desirable simply because it is more explicit, or it may be * necessary in order to distinguish between two {@code PlatformTransactionManager} beans * present in the same container. As the name suggests, the * {@code annotationDrivenTransactionManager()} will be the one used for processing * {@code @Transactional} methods. See {@link TransactionManagementConfigurer} Javadoc * for further details. * * <p>The {@link #mode()} attribute controls how advice is applied; if the mode is * {@link AdviceMode#PROXY} (the default), then the other attributes control the behavior * of the proxying. * * <p>If the {@linkplain #mode} is set to {@link AdviceMode#ASPECTJ}, then the * {@link #proxyTargetClass()} attribute is obsolete. Note also that in this case the * {@code spring-aspects} module JAR must be present on the classpath. * * @author Chris Beams * @since 3.1 * @see TransactionManagementConfigurer * @see TransactionManagementConfigurationSelector * @see ProxyTransactionManagementConfiguration * @see org.springframework.transaction.aspectj.AspectJTransactionManagementConfiguration */ @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Import(TransactionManagementConfigurationSelector.class) public @interface EnableTransactionManagement { /** * Indicate whether subclass-based (CGLIB) proxies are to be created ({@code true}) as * opposed to standard Java interface-based proxies ({@code false}). The default is * {@code false}. <strong>Applicable only if {@link #mode()} is set to * {@link AdviceMode#PROXY}</strong>. * <p>Note that setting this attribute to {@code true} will affect <em>all</em> * Spring-managed beans requiring proxying, not just those marked with * {@code @Transactional}. For example, other beans marked with Spring's * {@code @Async} annotation will be upgraded to subclass proxying at the same * time. This approach has no negative impact in practice unless one is explicitly * expecting one type of proxy vs another, e.g. in tests. */ boolean proxyTargetClass() default false; /** * Indicate how transactional advice should be applied. The default is * {@link AdviceMode#PROXY}. * @see AdviceMode */ AdviceMode mode() default AdviceMode.PROXY; /** * Indicate the ordering of the execution of the transaction advisor * when multiple advices are applied at a specific joinpoint. * The default is {@link Ordered#LOWEST_PRECEDENCE}. */ int order() default Ordered.LOWEST_PRECEDENCE; }