Spring Framework Actual Warfare: AOP

1 Overview

AspectJ supports the facet programming of Spring.

The foundation that AOP needs to understand:

  1. Declare a facet with @Aspect.
  2. @After, @Before, @Around Definition Advice;The parameters of these three annotations are PointCut, which is actually an interception rule (which can be defined by annotations or method rules).
  3. You can define a tangent point using @PonitCut and place it as a parameter at @After, @Before, @Around, so that you can reuse the tangent point.
  4. Every place that meets the interception criteria is also a JoinPoint.

2 AOP example

The following demonstrates two ways to define a tangent point:
Cut points based on custom annotations and method rules.

The code used in this example is already in place On GitHub.

2.1 Customize a point of tangency comment@MyAction

Customize a comment @MyAction to mark the location of the point of tangency:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyAction {
    String name();
}

Annotations themselves have no functionality, just like xml.
Annotations and xml are metadata (data that interprets data), also known as configurations.
Annotations need to be resolved by other programs to be useful.
MyAction in Face Definition Is resolved into tangent points.

2.2 Define two methods to test points

Define two methods on which to test the point of tangency:

@Service
public class TestService {
    public void method1() {
        System.out.println("execute first method..");
    }

    @MyAction(name = "Custom Notes")
    public void method2() {
        System.out.println("execute second method..");
    }
}

2.3 Define a facet

@Aspect // Declare a Face
@Component
public class TestAspect {
    // @Pointcut is used to define the point of tangency.The method with the @MyAction comment is treated as a point of tangency here.
    @Pointcut("@annotation(cn.mitrecx.learn2aop.aop.MyAction)")
    public void annotationPointCut() {
    }

    /**
     * After Comments are used to declare an assertion using the tangent points defined by annotation PointCut().
     * After The annotated method is executed after the tangent point is executed.
     * In other words, after the tangent method executes, the afterExecution method is executed immediately.
     */
    // @After("@annotation(cn.mitrecx.learn2aop.aop.MyAction)")//is equivalent to @After below
    @After("annotationPointCut()")
    public void afterExecution(JoinPoint joinPoint) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        MyAction action = method.getAnnotation(MyAction.class);
        System.out.println("After(Annotation Intercept): " + action.name());
    }

    /**
     * Before Comments are used to declare an assertion, where the tangent points defined by the rule are used.
     * Method rule <code>execution(* cn.mitrecx.learn2aop.aop.TestService. *(.))</code>represents all methods of {@link TestService}.
     * <p>
     * In short, the beforeExecution method is executed before any of the {@link TestService} methods start execution.
     */
    @Before("execution(* cn.mitrecx.learn2aop.aop.TestService.*(..))")
    public void beforeExecution(JoinPoint joinPoint) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        System.out.println("Before(Method regular interception): " + method.getName());
    }
}

The above @Before usage rule style cut-point is not good, it will cause code logic to be unclear.
Because we can't see the method "tampered" directly from the method in the TestService class (beforeExecution() logic added).

2.4 Configuration Class

@Configuration
@ComponentScan("cn.mitrecx.learn2aop.aop")
@EnableAspectJAutoProxy
public class AopConfig {
}

2.5 Main Program

public class MyApplication {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context =
                new AnnotationConfigApplicationContext(AopConfig.class);

        TestService testService = context.getBean(TestService.class);

        testService.method1();
        System.out.println("---------");
        testService.method2();

        context.close();
    }
}

Run result:

Before(Method regular interception): method1
execute first method..
---------
Before(Method regular interception): method2
execute second method..
After(Annotation Intercept): Custom Notes

The results show that the @Before assertion of the regular tangent points (methed1, methed2) of the two methods is executed before the tangent point method is executed.
The @After assertion of the annotated tangent (methed2) is executed after the tangent method is executed.

Be careful:
Here are just two ways to define a point of tangency.
Personally, I recommend using only annotated tangent points, as it looks clearer.

Reference

[1].Spring Boot Actual Warfare - Wong Yunfei

Tags: Java Spring

Posted on Tue, 05 Oct 2021 12:19:36 -0400 by RobinTibbs