Search code examples
javaspringaopaspectjpointcut

Pointcut or Aspect Around All Service Methods with Annotation @Transactional(readOnly = false)


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[??])


Solution

  • 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.