Using AspectJ LTW to provide spring proxy functionality for self-starting non-public methods and related considerations

I have seen numerous examples of Spring functionality associated with @Cacheable, @Transactional, @Asyncetc., where the same parameters are repeated each time:

  • Moving the target method to a separate class @Service,

  • Using AspectJ to load in time.

While the first two approaches are usually fine, there are times when we need to attach the functionality of three (and other) annotations to private methods, whether for clarity of code, design, or for other reasons.


, . , AspectJ LTW Spring AOP, @Cacheable .. :

  • , , AspectJ LTW?

  • AspectJ LTW , . @Async @Transactional, @Cacheable? : - , ( ) , , , (.. 'last-queried-at: #') .

spring-boot, , Spring AOP AspectJ LTW. , , .

+6
1
  • , AspectJ LTW?

AspectJ GitHub. , (self-invocation), .

, , .

"README", , .

  1. AspectJ LTW , . @Async @Transactional, @Cacheable?

, :

  • .

    @Before("call(* com.basaki.service.UselessService.sayHello(..))" +
            "  && cflow(@annotation(trx))")
    public void inspectMethod(JoinPoint jp,
            JoinPoint.EnclosingStaticPart esjp, Transactional trx) {
        log.info(
                "Entering FilterCallerAnnotationAspect.inspectMethod() in class "
                        + jp.getSignature().getDeclaringTypeName()
                        + " - method: " + jp.getSignature().getName());
    }
    
  • .

    @Before("call(* com.basaki.service.UselessService.sayHello(..))" +
            "  && cflow(execution(* com.basaki.service.BookService.read(..)))")
    public void inspectMethod(JoinPoint jp,
            JoinPoint.EnclosingStaticPart esjp) {
        log.info(
                "Entering FilterCallerMethodAspect.inspectMethod() in class "
                        + jp.getSignature().getDeclaringTypeName()
                        + " - method: " + jp.getSignature().getName());
    }
    

.

Q. , , : 1. TransactionAwareDataSourceProxy DataSource; 2. : @EnableTransactionManagement (mode = AdviceMode.ASPECTJ).

Spring AOP CTW/LTW , .. .

  • LTW -, .
  • AOP -, .. . - Spring. Spring AOP CTW/LTW, . Spring AOP .

@EnableTransactionManagement, Spring , .

Q. , - CTW. , - ?

, CTW , - AspectJ (ajc) . , :

@CustomAnnotation(description = "Validates book request.")
private Book validateRequest(BookRequest request) {
    log.info("Validating book request!");

    Assert.notNull(request, "Book request cannot be empty!");
    Assert.notNull(request.getTitle(), "Book title cannot be missing!");
    Assert.notNull(request.getAuthor(), "Book author cannot be missing!");

    Book entity = new Book();
    entity.setTitle(request.getTitle());
    entity.setAuthor(request.getAuthor());

    return entity;
}

AspectJ, ajc:

private Book validateRequest(BookRequest request) {
    JoinPoint var3 = Factory.makeJP(ajc$tjp_0, this, this, request);
    CustomAnnotationAspect var10000 = CustomAnnotationAspect.aspectOf();
    Annotation var10002 = ajc$anno$0;
    if (ajc$anno$0 == null) {
        var10002 = ajc$anno$0 = BookService.class.getDeclaredMethod("validateRequest", BookRequest.class).getAnnotation(CustomAnnotation.class);
    }

    var10000.inspectMethod(var3, (CustomAnnotation)var10002);

    log.info("Validating book request!");
    Assert.notNull(request, "Book request cannot be empty!");
    Assert.notNull(request.getTitle(), "Book title cannot be missing!");
    Assert.notNull(request.getAuthor(), "Book author cannot be missing!");

    Book entity = new Book();
    entity.setTitle(request.getTitle());
    entity.setAuthor(request.getAuthor());
    return entity;
}

LTW Java, , Java.

+3

All Articles