Spring documentation advises putting the @Transactional annotation on the concrete class/method rather than the interface. The reason for this has been covered on Stack Overflow many times, eg:
Where should I put @Transactional annotation: at an interface definition or at an implementing class?
Spring Security @Secured behaviour differs; most documentation shows placing the annotation on the interface. In fact it seems to work whether you annotate the interface or the concrete class and regardless of whether you use JDK or CGLib proxies.
This seems a superior solution. So why the inconsistency? One answer to the above question suggests a performance impact... but surely performance is just as important to security?!
And how does the @Secured solution deal with the diamond inheritance problem (class implements 2 interfaces both have @Secured same method differently)?
When using both JDK proxies and CGLib You end up with TransactionInterceptor for @Transactional and MethodSecurityInterceptor for @Secured.
But those two MethodInterceptors use diffrent mechanisms to find annotation on given MethodInvocation.
@Secured annotation is found by SecuredAnnotationSecurityMetadataSource using AnnotationUtils.findAnnotation(Method method, Class<A> annotationType) method, while @Transactional is discovered by AnnotationTransactionAttributeSource with help of SpringTransactionAnnotationParser.
It looks like AnnotationUtils have much more advanced mechanisms of finding annotations, seraching both the interfaces and the method declaring class hierarchy.
You could create Your own TransactionAnnotationParser that uses AnnotationUtils and this should enable same functioanlity to @Transactional.
AnnotationUtils returns the first found annotation, so that's how diamond inheritance is dealt with.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With