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