Polish @EnableTransactionManagement Javadoc and XSD
git-svn-id: https://src.springframework.org/svn/spring-framework/trunk@4411 50f2f4bb-b051-0410-bef5-90022cba6387
This commit is contained in:
parent
9c73be0869
commit
d9ce5f854c
|
|
@ -21,8 +21,19 @@ import org.springframework.context.annotation.Bean;
|
|||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Role;
|
||||
import org.springframework.transaction.annotation.AbstractTransactionManagementConfiguration;
|
||||
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||
import org.springframework.transaction.annotation.TransactionManagementConfigurationSelector;
|
||||
import org.springframework.transaction.config.TransactionManagementConfigUtils;
|
||||
|
||||
/**
|
||||
* {@code @Configuration} class that registers the Spring infrastructure beans necessary
|
||||
* to enable AspectJ-based annotation-driven transaction management.
|
||||
*
|
||||
* @author Chris Beams
|
||||
* @since 3.1
|
||||
* @see EnableTransactionManagement
|
||||
* @see TransactionManagementConfigurationSelector
|
||||
*/
|
||||
@Configuration
|
||||
public class AspectJTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {
|
||||
|
||||
|
|
|
|||
|
|
@ -27,8 +27,8 @@ import org.springframework.transaction.PlatformTransactionManager;
|
|||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Abstract base class providing common structure for enabling Spring's annotation-
|
||||
* driven transaction management capability.
|
||||
* Abstract base {@code @Configuration} class providing common structure for enabling
|
||||
* Spring's annotation-driven transaction management capability.
|
||||
*
|
||||
* @author Chris Beams
|
||||
* @since 3.1
|
||||
|
|
|
|||
|
|
@ -26,6 +26,114 @@ import org.springframework.context.annotation.Import;
|
|||
import org.springframework.context.config.AdviceMode;
|
||||
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 @Transacational}
|
||||
* 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>Note that 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.<p>
|
||||
*
|
||||
* @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
|
||||
|
|
@ -33,11 +141,12 @@ import org.springframework.core.Ordered;
|
|||
public @interface EnableTransactionManagement {
|
||||
|
||||
/**
|
||||
* Indicate whether class-based (CGLIB) proxies are to be created as opposed
|
||||
* to standard Java interface-based proxies. The default is {@code false}.
|
||||
* Indicate whether subclass-based (CGLIB) proxies are to be created as opposed
|
||||
* to standard Java interface-based proxies. The default is {@code false}. <strong>
|
||||
* Applicable only if {@link #mode()} is set to {@link AdviceMode#PROXY}</strong>.
|
||||
*
|
||||
* <p>Note: Class-based proxies require the {@link Transactional @Transactional}
|
||||
* annotation to be defined on the concrete class. Annotations in interfaces will
|
||||
* <p>Note that subclass-based proxies require the {@link Transactional @Transactional}
|
||||
* to be defined on the concrete class. Annotations in interfaces will
|
||||
* not work in that case (they will rather only work with interface-based proxies)!
|
||||
*/
|
||||
boolean proxyTargetClass() default false;
|
||||
|
|
@ -52,7 +161,7 @@ public @interface EnableTransactionManagement {
|
|||
/**
|
||||
* Indicate the ordering of the execution of the transaction advisor
|
||||
* when multiple advices are applied at a specific joinpoint.
|
||||
* The default is lowest priority.
|
||||
* The default is {@link Ordered#LOWEST_PRECEDENCE}.
|
||||
*/
|
||||
int order() default Ordered.LOWEST_PRECEDENCE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,15 @@ import org.springframework.transaction.interceptor.BeanFactoryTransactionAttribu
|
|||
import org.springframework.transaction.interceptor.TransactionAttributeSource;
|
||||
import org.springframework.transaction.interceptor.TransactionInterceptor;
|
||||
|
||||
/**
|
||||
* {@code @Configuration} class that registers the Spring infrastructure beans necessary
|
||||
* to enable proxy-based annotation-driven transaction management.
|
||||
*
|
||||
* @author Chris Beams
|
||||
* @since 3.1
|
||||
* @see EnableTransactionManagement
|
||||
* @see TransactionManagementConfigurationSelector
|
||||
*/
|
||||
@Configuration
|
||||
public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {
|
||||
|
||||
|
|
|
|||
|
|
@ -23,8 +23,26 @@ import org.springframework.context.config.AdviceMode;
|
|||
import org.springframework.core.type.AnnotationMetadata;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Selects which implementation of {@link AbstractTransactionManagementConfiguration}
|
||||
* should be used based on the value of {@link EnableTransactionManagement#mode} on the
|
||||
* importing @{@link Configuration} class.
|
||||
*
|
||||
* @author Chris Beams
|
||||
* @since 3.1
|
||||
* @see EnableTransactionManagement
|
||||
* @see AbstractTransactionManagementConfiguration
|
||||
* @see ProxyTransactionManagementConfiguration
|
||||
* @see org.springframework.transaction.aspectj.AspectJTransactionManagementConfiguration
|
||||
*/
|
||||
public class TransactionManagementConfigurationSelector implements ImportSelector {
|
||||
|
||||
/**
|
||||
* Import {@link ProxyTransactionManagementConfiguration} if {@link
|
||||
* EnableTransactionManagement#mode()} equals {@code PROXY}, otherwise import {@link
|
||||
* org.springframework.transaction.aspectj.AspectJTransactionManagementConfiguration
|
||||
* AspectJTransactionManagementConfiguration}.
|
||||
*/
|
||||
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
|
||||
Map<String, Object> enableTx =
|
||||
importingClassMetadata.getAnnotationAttributes(EnableTransactionManagement.class.getName());
|
||||
|
|
|
|||
|
|
@ -18,8 +18,66 @@ package org.springframework.transaction.annotation;
|
|||
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
|
||||
/**
|
||||
* Interface to be implemented by @{@link org.springframework.context.annotation.Configuration
|
||||
* Configuration} classes annotated with @{@link EnableTransactionManagement} that wish
|
||||
* or need to specify explicitly the {@link PlatformTransactionManager} bean to be used
|
||||
* for annotation-driven transaction management, as opposed to the default approach of a
|
||||
* by-type lookup. One reason this might be necessary is if there are two
|
||||
* {@code PlatformTransactionManager} implementations present in the container.
|
||||
*
|
||||
* <p>See @{@link EnableTransactionManagement} for general examples and context; see
|
||||
* {@link #annotationDrivenTransactionManager()} below for detailed instructions.
|
||||
*
|
||||
* <p>Note that in by-type lookup disambiguation cases, an alternative approach to
|
||||
* implementing this interface is to simply mark one of the offending {@code
|
||||
* PlatformTransactionManager} {@code @Bean} methods as @{@link
|
||||
* org.springframework.context.annotation.Primary Primary}.
|
||||
*
|
||||
* @author Chris Beams
|
||||
* @since 3.1
|
||||
* @see EnableTransactionManagement
|
||||
* @see org.springframework.context.annotation.Primary
|
||||
*/
|
||||
public interface TransactionManagementConfigurer {
|
||||
|
||||
/**
|
||||
* Return the transaction manager bean to use for annotation-driven database
|
||||
* transaction management, i.e. when processing {@code @Transactional} methods.
|
||||
*
|
||||
* <p>There are two basic approaches to implementing this method:
|
||||
* <h3>1. Implement the method and annotate it with {@code @Bean}</h3>
|
||||
* In this case, the implementing {@code @Configuration} class implements this method,
|
||||
* marks it with {@code @Bean} and configures and returns the transaction manager
|
||||
* directly within the method body:
|
||||
* <pre class="code">
|
||||
* @Bean
|
||||
* @Override
|
||||
* public PlatformTransactionManager createTransactionManager() {
|
||||
* return new DataSourceTransactionManager(dataSource());
|
||||
* }</pre>
|
||||
* <h3>2. Implement the method without {@code @Bean} and delegate to another existing
|
||||
* {@code @Bean} method</h3>
|
||||
* <pre class="code">
|
||||
* @Bean
|
||||
* public PlatformTransactionManager txManager() {
|
||||
* return new DataSourceTransactionManager(dataSource());
|
||||
* }
|
||||
*
|
||||
* @Override
|
||||
* public PlatformTransactionManager createTransactionManager() {
|
||||
* return txManager(); // reference the existing {@code @Bean} method above
|
||||
* }</pre>
|
||||
*
|
||||
* If taking approach #2, be sure that <em>only one</em> of the methods is marked with
|
||||
* {@code @Bean}!
|
||||
*
|
||||
* <p>In either scenario #1 or #2, it is important that the
|
||||
* {@code PlatformTransactionManager} instance is managed as a Spring bean within the
|
||||
* container as all {@code PlatformTransactionManager} implementations take
|
||||
* advantage of Spring lifecycle callbacks such as {@code InitializingBean} and {@code
|
||||
* BeanFactoryAware}.
|
||||
*/
|
||||
PlatformTransactionManager annotationDrivenTransactionManager();
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -76,6 +76,9 @@
|
|||
|
||||
Transaction semantics such as propagation settings, the isolation level,
|
||||
the rollback rules, etc are all defined in the annotation metadata.
|
||||
|
||||
See org.springframework.transaction.annotation.EnableTransactionManagement Javadoc
|
||||
for information on code-based alternatives to this XML element.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:attribute name="transaction-manager" type="xsd:string" default="transactionManager">
|
||||
|
|
|
|||
Loading…
Reference in New Issue