Spring AOP aspect section guide

Spring Aspect cheatsheet

Put some easy-to-use spring aspect syntax manuals.

use

Full code: spring-aop

  1. import library, reference build.gradle
  2. Aspects are marked with @Aspect and @Configuration. refer to LogingAspect

Why?

Just like the btrace manual written before, in order to facilitate the search and actual operation, I would like to share some cheatsheet s related to writing Aspect.

concept

  1. Aspect

    As a modular set of concerns, cross-sections in many classes. For example, transaction management @Transactional is a cross-section related to transactions in enterprise applications. Or an aspect for logging. Typically a section will contain a complete
    meaningful collection of . Generally, Pointcut definitions and Advice definitions are included.
  2. Join Point

    Represents a point of program execution. Represents the execution point of a method in spring.
  3. Advice

    At a particular Join Point, the operation taken by Aspect. Contains different types (around, before, after). Many aop frameworks include
    spring implements Advice with interceptors, and maintains an interceptor chain to handle multiple Advices of a JointPoint.
  4. Pointcut

    Define method aspects that satisfy some defined conditions. Advice will be executed on all JoinPoint s that satisfy the Pointcut. For example, Pointcut can be defined as
    Execute (within(com.example.controller.*)) on all Controller methods. This article will also provide more examples for easy search.
  5. Introduction

    Add new methods or properties on a class basis. For example, a property IsModified can be introduced for some bean s to facilitate caching.
  6. Target object

    A class object (also called an advised object) waiting to be enhanced by an aspect. Because spring is implemented by proxy, this is also called the proxy object.
  7. AOP proxy
    `
    In order to implement aspect, the enhanced object implemented by JDK dynamic proxy, or cglib proxy.
  8. Weaving

    The process of combining multiple aspects and real applications can be implemented at compile time (aspectj compiler), load time, and runtime (spring aop).

Advice type

  1. Before
  2. AfterReturning
  3. AfterThrowing
  4. Around

    around advice will have a ProceedingJoinPoint parameter. This is the strongest type of advice. It provides the proceed method to
    Call the original logic. Several other Advie s are similar to the read-only type, and only provide a parameter of the JoinPoint type.

Common examples of PointCut

exampleexplain
within(com.xyz.service.*)Implement methods of all classes of com.xyz.service (excluding subpackages)
within(com.xyz.service..*)Implement methods of all classes of com.xyz.service (including subpackages)
this(com.xyz.service.AccountService)Execute the class that implements the interface of AccountService
execution(* com.example.springaop.controller.*.*(..))implement
execution(public * *(..))Execute all public methods
execution(* set*(..))Execute all methods whose method name starts with set
execution(* com.xyz.service.AccountService.*(..))Executes all methods in the com.xyz.service.AccountService class.
execution(* com.xyz.service.*.*(..))Execute all methods in com.xyz.service (excluding subpackages)
execution(* com.xyz.service..*.*(..))Execute all methods in com.xyz.service (including subpackages)
@within(org.springframework.transaction.annotation.Transactional)A class has @Transactional annotation
@annotation(org.springframework.transaction.annotation.Transactional)A method has @Transactional annotation

Concrete syntax:
execution(modifiers-pattern? ret-type-pattern declaring-type-pattern?name-pattern(param-pattern) throws-pattern?)

Advice usage example

  1. Before
    Before the method starts to execute, you can use JoinPoint to get the status of the currently executing method. This parameter can be obtained for the subsequent several.
    @Before("execution(* com.xyz.myapp.dao.*.*(..))")
    public void doAccessCheck(JoinPoint jp) {
    
    }
  1. AfterReturning

    After returning normally:

    @AfterReturning(
         pointcut="com.xyz.myapp.CommonPointcuts.dataAccessOperation()",
         returning="retVal")
     public void doAccessCheck(Object retVal) {
         // ...
     }
    
  2. AfterThrowing

    After throwing an exception:

    @AfterThrowing(
        pointcut="com.xyz.myapp.CommonPointcuts.dataAccessOperation()",
        throwing="ex")
    public void doRecoveryActions(DataAccessException ex) {
        // ...
    } 
    
  3. Arround
    Around advice can use ProceedingJoinPoint.proceed to call the original implementation.

   @Around("com.xyz.myapp.CommonPointcuts.businessService()")
   public Object timing(ProceedingJoinPoint jp) throws Throwable {
        // start stopwatch
        Object retVal = jp.proceed(); 
        // stop stopwatch
        return retVal;
   }   
  1. Pass parameters to Advice.
    In addition to the parameters that can be obtained by the above JoinPoint, you can also obtain them in the following ways:
@Before("com.xyz.myapp.CommonPointcuts.dataAccessOperation() && args(account,..)")
public void validateAccount(Account account) {
    // ...
}

account is the first parameter in the above example. Of course, the PointCut specified by dataAccessOperation must have at least one parameter.

  1. Order of Advice
    Execute in the following order:
@Around, @Before, @After, @AfterReturning, @AfterThrowing

Different Aspect s can also specify the order through @Order

a complete example

Example for counting elapsed time and logging requests:

package com.example.springaop;

import org.aspectj.lang.*;
import org.aspectj.lang.annotation.*;
import org.springframework.context.annotation.*;

import java.util.*;

@Configuration
@Aspect
public class LogingAspect {

    @Pointcut("within(com.example.springaop.controller.*)")
    public void ctrlMethod() {

    }

    @Pointcut("execution(public * *(..)) ")
    public void publicMethod() {}

    @Around("ctrlMethod() && publicMethod()")
    public Object loggingAndTiming(ProceedingJoinPoint jp) throws Throwable {
        long t1 = System.currentTimeMillis();
        String className = jp.getSignature().getDeclaringTypeName();
        String methodName = jp.getSignature().getName();
        String args = Arrays.toString(jp.getArgs());
        try {
            return jp.proceed();
        } catch (Throwable e) {
            throw e;
        }
        finally {
            System.out.println(String.format("%s.%s with args: %s , cost time: %d",
                    className, methodName, args, System.currentTimeMillis() - t1));
        }
    }
}

refer to

  1. spring official website documentation

Tags: Java Spring Back-end

Posted by jimdidr on Sat, 03 Dec 2022 20:28:34 +0530