1

Is it possible to use Spring AOP or AspectJ to intercept all Service methods (contained in classes in the com.app.service.* package) having the annotation

@Transactional(readOnly = false)

(other elements possible as well in Spring's @Transactional annotation, but we only care about readOnly = false).

I could only find examples pertaining to pointcuts with simple Annotations, or @Annotation(value).

My preference would be to use straight Spring, if possible.

It would probably be something like the below, but not sure about the syntax.

@Around("execution(* com.app.service..*.*(..))" && @Transactional[??])

gene b.
  • 10,512
  • 21
  • 115
  • 227
  • That should be possible. I've worked sometime back on spring and I remember using a xml configuration to achieve the same. We used to mark all transactions as read only and explicitly configure required ones to be able write. – Leela Venkatesh K Nov 19 '18 at 21:29

2 Answers2

0

You want to use a pointcut like this:

execution(@org.springframework.transaction.annotation.Transactional(readOnly = false) * com.app.service..*.*(..))
kriegaex
  • 63,017
  • 15
  • 111
  • 202
  • The issue I came across with this one is, I had to get a `Transactional t` argument to examine the object. And whenever I had this argument, the app wouldn't start (there was an error). It worked when I had a simple signature, without the actual `Transactional t` object. – gene b. Nov 26 '18 at 15:12
  • I do not understand what you just wrote. – kriegaex Nov 29 '18 at 05:25
-1

Unfortunately no easy way to do that. Even when we have an Annotation-based pointcut, e.g.

@Aspect
@Component
@EnableAspectJAutoProxy
public class WriteTransactionAspectBean {

    @Before("@annotation(org.springframework.transaction.annotation.Transactional)")
    public void test(org.springframework.transaction.annotation.Transactional t) {
        System.out.println("TEST");
    }

}

the issue is the Annotations aren't our own, they come from an external JAR (Hibernate). This would require Load-Time Weaving or some other difficult workaround.

Aspectj: intercept method from external jar

But to make things even worse, Annotations need RetentionPolicy=RUNTIME in order to be "discovered" by Pointcuts. And we would need to go thru every method and add this specification to every @Transactional. There's no way to automatically make all @Transactional's Runtime-retainable in the application.

gene b.
  • 10,512
  • 21
  • 115
  • 227
  • This answer is plain wrong. The `@Transactional` annotation is defined with runtime scope as you can clearly see in the corresponding [JavaDoc](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/transaction/annotation/Transactional.html). Otherwise Spring could not do anything with it either. – kriegaex Nov 25 '18 at 08:27