@ -34,6 +34,7 @@ import org.springframework.core.BridgeMethodResolver;
@@ -34,6 +34,7 @@ import org.springframework.core.BridgeMethodResolver;
import org.springframework.dao.support.PersistenceExceptionTranslationInterceptor ;
import org.springframework.data.repository.core.RepositoryInformation ;
import org.springframework.transaction.annotation.Ejb3TransactionAnnotationParser ;
import org.springframework.transaction.annotation.JtaTransactionAnnotationParser ;
import org.springframework.transaction.annotation.SpringTransactionAnnotationParser ;
import org.springframework.transaction.annotation.TransactionAnnotationParser ;
import org.springframework.transaction.annotation.Transactional ;
@ -110,10 +111,10 @@ class TransactionalRepositoryProxyPostProcessor implements RepositoryProxyPostPr
@@ -110,10 +111,10 @@ class TransactionalRepositoryProxyPostProcessor implements RepositoryProxyPostPr
* working with transaction metadata in JDK 1 . 5 + annotation format .
* < p >
* This class reads Spring ' s JDK 1 . 5 + { @link Transactional } annotation and exposes corresponding transaction
* attributes to Spring ' s transaction infrastructure . Also supports EJB3 ' s { @link javax . ejb . TransactionAttribute }
* annotation ( if present ) . This class may also serve as base class for a custom TransactionAttributeSource , or get
* customized through { @link TransactionAnnotationParser } strategies .
*
* attributes to Spring ' s transaction infrastructure . Also supports JTA 1 . 2 ' s and EJB3 ' s
* { @link javax . ejb . TransactionAttribute } annotation ( if present ) . This class may also serve as base class for a
* custom TransactionAttributeSource , or get custom ized through { @link TransactionAnnotationParser } strategies .
*
* @author Colin Sampaleanu
* @author Juergen Hoeller
* @since 1 . 2
@ -124,43 +125,50 @@ class TransactionalRepositoryProxyPostProcessor implements RepositoryProxyPostPr
@@ -124,43 +125,50 @@ class TransactionalRepositoryProxyPostProcessor implements RepositoryProxyPostPr
* @see org . springframework . transaction . interceptor . TransactionInterceptor # setTransactionAttributeSource
* @see org . springframework . transaction . interceptor . TransactionProxyFactoryBean # setTransactionAttributeSource
* /
static class CustomAnnotationTransactionAttributeSource extends AbstractFallbackTransactionAttributeSource implements
Serializable {
@SuppressWarnings ( "serial" )
static class CustomAnnotationTransactionAttributeSource extends AbstractFallbackTransactionAttributeSource
implements Serializable {
private static final boolean jta12Present = ClassUtils . isPresent ( "javax.transaction.Transactional" ,
CustomAnnotationTransactionAttributeSource . class . getClassLoader ( ) ) ;
private static final long serialVersionUID = 4841944452113159864L ;
private static final boolean ejb3Present = ClassUtils . isPresent ( "javax.ejb.TransactionAttribute" ,
CustomAnnotationTransactionAttributeSource . class . getClassLoader ( ) ) ;
private final boolean publicMethodsOnly ;
private final Set < TransactionAnnotationParser > annotationParsers ;
/ * *
* Create a default AnnotationTransactionAttributeSource , supporting public methods that carry the
* < code > Transactional < / code > annotation or the EJB3 { @link javax . ejb . TransactionAttribute } annotation .
* Create a default Custom AnnotationTransactionAttributeSource, supporting public methods that carry the
* { @code Transactional } annotation or the EJB3 { @link javax . ejb . TransactionAttribute } annotation .
* /
public CustomAnnotationTransactionAttributeSource ( ) {
this ( true ) ;
}
/ * *
* Create a custom AnnotationTransactionAttributeSource , supporting public methods that carry the
* < code > Transactional < / code > annotation or the EJB3 { @link javax . ejb . TransactionAttribute } annotation .
* Create a custom Custom AnnotationTransactionAttributeSource, supporting public methods that carry the
* { @code Transactional } annotation or the EJB3 { @link javax . ejb . TransactionAttribute } annotation .
*
* @param publicMethodsOnly whether to support public methods that carry the < code > Transactional < / code > annotation
* only ( typically for use with proxy - based AOP ) , or protected / private methods as well ( typically used with
* @param publicMethodsOnly whether to support public methods that carry the { @code Transactional } annotation only
* ( typically for use with proxy - based AOP ) , or protected / private methods as well ( typically used with
* AspectJ class weaving )
* /
public CustomAnnotationTransactionAttributeSource ( boolean publicMethodsOnly ) {
this . publicMethodsOnly = publicMethodsOnly ;
this . annotationParsers = new LinkedHashSet < TransactionAnnotationParser > ( 2 ) ;
this . annotationParsers . add ( new SpringTransactionAnnotationParser ( ) ) ;
if ( jta12Present ) {
this . annotationParsers . add ( new JtaTransactionAnnotationParser ( ) ) ;
}
if ( ejb3Present ) {
this . annotationParsers . add ( new Ejb3TransactionAnnotationParser ( ) ) ;
}
}
/ * *
* Create a custom AnnotationTransactionAttributeSource .
* Create a custom Custom AnnotationTransactionAttributeSource.
*
* @param annotationParser the TransactionAnnotationParser to use
* /
@ -171,7 +179,21 @@ class TransactionalRepositoryProxyPostProcessor implements RepositoryProxyPostPr
@@ -171,7 +179,21 @@ class TransactionalRepositoryProxyPostProcessor implements RepositoryProxyPostPr
}
/ * *
* Create a custom AnnotationTransactionAttributeSource .
* Create a custom CustomAnnotationTransactionAttributeSource .
*
* @param annotationParsers the TransactionAnnotationParsers to use
* /
public CustomAnnotationTransactionAttributeSource ( TransactionAnnotationParser . . . annotationParsers ) {
this . publicMethodsOnly = true ;
Assert . notEmpty ( annotationParsers , "At least one TransactionAnnotationParser needs to be specified" ) ;
Set < TransactionAnnotationParser > parsers = new LinkedHashSet < TransactionAnnotationParser > (
annotationParsers . length ) ;
Collections . addAll ( parsers , annotationParsers ) ;
this . annotationParsers = parsers ;
}
/ * *
* Create a custom CustomAnnotationTransactionAttributeSource .
*
* @param annotationParsers the TransactionAnnotationParsers to use
* /
@ -195,13 +217,12 @@ class TransactionalRepositoryProxyPostProcessor implements RepositoryProxyPostPr
@@ -195,13 +217,12 @@ class TransactionalRepositoryProxyPostProcessor implements RepositoryProxyPostPr
* Determine the transaction attribute for the given method or class .
* < p >
* This implementation delegates to configured { @link TransactionAnnotationParser TransactionAnnotationParsers } for
* parsing known annotations into Spring ' s metadata attribute class . Returns < code > null < / code > if it ' s not
* transactional .
* parsing known annotations into Spring ' s metadata attribute class . Returns { @code null } if it ' s not transactional .
* < p >
* Can be overridden to support custom annotations that carry transaction metadata .
*
* @param ae the annotated method or class
* @return TransactionAttribute the configured transaction attribute , or < code > null < / code > if none was found
* @return TransactionAttribute the configured transaction attribute , or { @code null } if none was found
* /
protected TransactionAttribute determineTransactionAttribute ( AnnotatedElement ae ) {
for ( TransactionAnnotationParser annotationParser : this . annotationParsers ) {
@ -220,6 +241,24 @@ class TransactionalRepositoryProxyPostProcessor implements RepositoryProxyPostPr
@@ -220,6 +241,24 @@ class TransactionalRepositoryProxyPostProcessor implements RepositoryProxyPostPr
protected boolean allowPublicMethodsOnly ( ) {
return this . publicMethodsOnly ;
}
@Override
public boolean equals ( Object other ) {
if ( this = = other ) {
return true ;
}
if ( ! ( other instanceof CustomAnnotationTransactionAttributeSource ) ) {
return false ;
}
CustomAnnotationTransactionAttributeSource otherTas = ( CustomAnnotationTransactionAttributeSource ) other ;
return ( this . annotationParsers . equals ( otherTas . annotationParsers )
& & this . publicMethodsOnly = = otherTas . publicMethodsOnly ) ;
}
@Override
public int hashCode ( ) {
return this . annotationParsers . hashCode ( ) ;
}
}
/ * *