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 * @Configuration 037 * @EnableTransactionManagement 038 * public class AppConfig { 039 * 040 * @Bean 041 * public FooRepository fooRepository() { 042 * // configure and return a class having @Transactional methods 043 * return new JdbcFooRepository(dataSource()); 044 * } 045 * 046 * @Bean 047 * public DataSource dataSource() { 048 * // configure and return the necessary JDBC DataSource 049 * } 050 * 051 * @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 * @Configuration 102 * @EnableTransactionManagement 103 * public class AppConfig implements TransactionManagementConfigurer { 104 * 105 * @Bean 106 * public FooRepository fooRepository() { 107 * // configure and return a class having @Transactional methods 108 * return new JdbcFooRepository(dataSource()); 109 * } 110 * 111 * @Bean 112 * public DataSource dataSource() { 113 * // configure and return the necessary JDBC DataSource 114 * } 115 * 116 * @Bean 117 * public PlatformTransactionManager txManager() { 118 * return new DataSourceTransactionManager(dataSource()); 119 * } 120 * 121 * @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}