001/*
002 * Copyright 2002-2017 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      https://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.transaction.annotation;
018
019import java.lang.annotation.Documented;
020import java.lang.annotation.ElementType;
021import java.lang.annotation.Retention;
022import java.lang.annotation.RetentionPolicy;
023import java.lang.annotation.Target;
024
025import org.springframework.context.annotation.AdviceMode;
026import org.springframework.context.annotation.Import;
027import org.springframework.core.Ordered;
028
029/**
030 * Enables Spring's annotation-driven transaction management capability, similar to
031 * the support found in Spring's {@code <tx:*>} XML namespace. To be used on
032 * {@link org.springframework.context.annotation.Configuration @Configuration}
033 * classes as follows:
034 *
035 * <pre class="code">
036 * &#064;Configuration
037 * &#064;EnableTransactionManagement
038 * public class AppConfig {
039 *
040 *     &#064;Bean
041 *     public FooRepository fooRepository() {
042 *         // configure and return a class having &#064;Transactional methods
043 *         return new JdbcFooRepository(dataSource());
044 *     }
045 *
046 *     &#064;Bean
047 *     public DataSource dataSource() {
048 *         // configure and return the necessary JDBC DataSource
049 *     }
050 *
051 *     &#064;Bean
052 *     public PlatformTransactionManager txManager() {
053 *         return new DataSourceTransactionManager(dataSource());
054 *     }
055 * }</pre>
056 *
057 * <p>For reference, the example above can be compared to the following Spring XML
058 * configuration:
059 *
060 * <pre class="code">
061 * {@code
062 * <beans>
063 *
064 *     <tx:annotation-driven/>
065 *
066 *     <bean id="fooRepository" class="com.foo.JdbcFooRepository">
067 *         <constructor-arg ref="dataSource"/>
068 *     </bean>
069 *
070 *     <bean id="dataSource" class="com.vendor.VendorDataSource"/>
071 *
072 *     <bean id="transactionManager" class="org.sfwk...DataSourceTransactionManager">
073 *         <constructor-arg ref="dataSource"/>
074 *     </bean>
075 *
076 * </beans>
077 * }</pre>
078 *
079 * In both of the scenarios above, {@code @EnableTransactionManagement} and {@code
080 * <tx:annotation-driven/>} are responsible for registering the necessary Spring
081 * components that power annotation-driven transaction management, such as the
082 * TransactionInterceptor and the proxy- or AspectJ-based advice that weave the
083 * interceptor into the call stack when {@code JdbcFooRepository}'s {@code @Transactional}
084 * methods are invoked.
085 *
086 * <p>A minor difference between the two examples lies in the naming of the {@code
087 * PlatformTransactionManager} bean: In the {@code @Bean} case, the name is
088 * <em>"txManager"</em> (per the name of the method); in the XML case, the name is
089 * <em>"transactionManager"</em>. The {@code <tx:annotation-driven/>} is hard-wired to
090 * look for a bean named "transactionManager" by default, however
091 * {@code @EnableTransactionManagement} is more flexible; it will fall back to a by-type
092 * lookup for any {@code PlatformTransactionManager} bean in the container. Thus the name
093 * can be "txManager", "transactionManager", or "tm": it simply does not matter.
094 *
095 * <p>For those that wish to establish a more direct relationship between
096 * {@code @EnableTransactionManagement} and the exact transaction manager bean to be used,
097 * the {@link TransactionManagementConfigurer} callback interface may be implemented -
098 * notice the {@code implements} clause and the {@code @Override}-annotated method below:
099 *
100 * <pre class="code">
101 * &#064;Configuration
102 * &#064;EnableTransactionManagement
103 * public class AppConfig implements TransactionManagementConfigurer {
104 *
105 *     &#064;Bean
106 *     public FooRepository fooRepository() {
107 *         // configure and return a class having &#064;Transactional methods
108 *         return new JdbcFooRepository(dataSource());
109 *     }
110 *
111 *     &#064;Bean
112 *     public DataSource dataSource() {
113 *         // configure and return the necessary JDBC DataSource
114 *     }
115 *
116 *     &#064;Bean
117 *     public PlatformTransactionManager txManager() {
118 *         return new DataSourceTransactionManager(dataSource());
119 *     }
120 *
121 *     &#064;Override
122 *     public PlatformTransactionManager annotationDrivenTransactionManager() {
123 *         return txManager();
124 *     }
125 * }</pre>
126 *
127 * This approach may be desirable simply because it is more explicit, or it may be
128 * necessary in order to distinguish between two {@code PlatformTransactionManager} beans
129 * present in the same container.  As the name suggests, the
130 * {@code annotationDrivenTransactionManager()} will be the one used for processing
131 * {@code @Transactional} methods. See {@link TransactionManagementConfigurer} Javadoc
132 * for further details.
133 *
134 * <p>The {@link #mode} attribute controls how advice is applied: If the mode is
135 * {@link AdviceMode#PROXY} (the default), then the other attributes control the behavior
136 * of the proxying. Please note that proxy mode allows for interception of calls through
137 * the proxy only; local calls within the same class cannot get intercepted that way.
138 *
139 * <p>Note that if the {@linkplain #mode} is set to {@link AdviceMode#ASPECTJ}, then the
140 * value of the {@link #proxyTargetClass} attribute will be ignored. Note also that in
141 * this case the {@code spring-aspects} module JAR must be present on the classpath, with
142 * compile-time weaving or load-time weaving applying the aspect to the affected classes.
143 * There is no proxy involved in such a scenario; local calls will be intercepted as well.
144 *
145 * @author Chris Beams
146 * @author Juergen Hoeller
147 * @since 3.1
148 * @see TransactionManagementConfigurer
149 * @see TransactionManagementConfigurationSelector
150 * @see ProxyTransactionManagementConfiguration
151 * @see org.springframework.transaction.aspectj.AspectJTransactionManagementConfiguration
152 */
153@Target(ElementType.TYPE)
154@Retention(RetentionPolicy.RUNTIME)
155@Documented
156@Import(TransactionManagementConfigurationSelector.class)
157public @interface EnableTransactionManagement {
158
159        /**
160         * Indicate whether subclass-based (CGLIB) proxies are to be created ({@code true}) as
161         * opposed to standard Java interface-based proxies ({@code false}). The default is
162         * {@code false}. <strong>Applicable only if {@link #mode()} is set to
163         * {@link AdviceMode#PROXY}</strong>.
164         * <p>Note that setting this attribute to {@code true} will affect <em>all</em>
165         * Spring-managed beans requiring proxying, not just those marked with
166         * {@code @Transactional}. For example, other beans marked with Spring's
167         * {@code @Async} annotation will be upgraded to subclass proxying at the same
168         * time. This approach has no negative impact in practice unless one is explicitly
169         * expecting one type of proxy vs another, e.g. in tests.
170         */
171        boolean proxyTargetClass() default false;
172
173        /**
174         * Indicate how transactional advice should be applied.
175         * <p><b>The default is {@link AdviceMode#PROXY}.</b>
176         * Please note that proxy mode allows for interception of calls through the proxy
177         * only. Local calls within the same class cannot get intercepted that way; an
178         * {@link Transactional} annotation on such a method within a local call will be
179         * ignored since Spring's interceptor does not even kick in for such a runtime
180         * scenario. For a more advanced mode of interception, consider switching this to
181         * {@link AdviceMode#ASPECTJ}.
182         */
183        AdviceMode mode() default AdviceMode.PROXY;
184
185        /**
186         * Indicate the ordering of the execution of the transaction advisor
187         * when multiple advices are applied at a specific joinpoint.
188         * <p>The default is {@link Ordered#LOWEST_PRECEDENCE}.
189         */
190        int order() default Ordered.LOWEST_PRECEDENCE;
191
192}