Some understanding and implementation of spring AOP

Posted by bznutz on Fri, 14 Jan 2022 07:34:40 +0100

Problem introduction (key points)

1 what is the target object?

2 how to find the method that the target object needs to be enhanced (modified)?

3 how to handle the methods to be enhanced (modified)?

Spring AOP related concepts

The bottom layer of Spring's AOP implementation is to encapsulate the code of the dynamic agent. After encapsulation, we only need to code the parts that need attention, and complete the method enhancement of the specified goal through configuration.

Common terms in AOP

Target(Target object)
The objects to be enhanced are generally objects of business logic classes.

Proxy((agent)
A class is AOP After weaving in the enhancement, a result proxy class is generated.

Aspect(section)
It refers to enhanced functions. It is a function completed by some code, not a business function.
Is a combination of pointcuts and notifications.

Joinpoint(Connection point)
The so-called connection points refer to those intercepted points. stay Spring in,These points refer to
 Methods (generally business methods in classes),because Spring Only connection points of method type are supported.

Pointcut(breakthrough point)
A pointcut is a collection of one or more declared join points. Specify a set of methods through pointcuts.
Marked as final Methods cannot be used as join points and pointcuts. Because the final
 It cannot be modified or enhanced.

Advice(notice/enhance)
The so-called notification refers to the interception of Joinpoint Then all you have to do is inform. Notification defined
 The point in time when the enhanced code cuts into the target code, whether it is executed before or after the execution of the target method
 OK, wait. Different notification types lead to different cut in times.
Type of notification: pre notification,Post notification,Exception notification,Final notice,Surround notification.

Weaving(Weave in).
Refers to the process of applying enhancements to the target object to create a new proxy object. spring Adopt dynamic
 Agent weaving in, and AspectJ Compile time weaving and class load time weaving are adopted.

Implementation of AOP by AspectJ

Notification type for AspectJ

  • 1. Advance notice
  • 2 post notification
  • 3. Circular notice
  • 4. Exception notification
  • 5. Final notice

Pointcut expression for AspectJ

AspectJ A special expression is defined to specify the pointcut.
The prototype of the expression is as follows:
execution(modifiers-pattern? ret-type-pattern
declaring-type-pattern?name-pattern(param-pattern)
throws-pattern?)
explain:
modifiers-pattern] Access type
ret-type-pattern return type
declaring-type-pattern Package name class name
name-pattern(param-pattern) Method name(Parameter type and number)
throws-pattern Throw exception type
´╝čRepresents an optional part

The above expression consists of four parts.
Execution (access permission method return value method declaration (parameter) exception type)
The object to be matched by the pointcut expression is the method name of the target method. Therefore, the execution expression is the signature of the method.
PS: black text in the expression indicates the parts that can be omitted, and the parts are separated by spaces. The following symbols can be used:

Symbolsignificance
*0 - multiple arbitrary characters
. .Used in method parameters to represent any parameter; Used after the package name to indicate the current and its sub package paths
+Used after the class name to represent the current and its subclasses; Used after an interface to represent the current interface and its implementation class

Where + not commonly used

Example:
execution(* com.cave.service.*.*(..))
The specified pointcut is: defined in service Any method of any class in the package.

execution(* com.cave.service..*.*(..))
The specified pointcut is: defined in service Any method of any class in a package or sub package. “.."When it appears in the class name, it must be followed by
"*"´╝îRepresents all classes under package and sub package.

execution(* com.cave.service.IUserService+.*(..))
The specified entry point is: IUserService If it is an interface, it is any method in the interface and any method in all its implementation classes; In case of class,
Is any method in this class and its subclasses.

Implement AOP by annotation

1. Create project dependencies

<dependencies>
        <!--spring Core dependency-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.13.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>5.2.13.RELEASE</version>
        </dependency>
        <!--Test dependency-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
</dependencies>
<build>
    <plugins>
        <!--Compiling plug-ins-->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.8.0</version>
            <configuration>
            <source>1.8</source>
            <target>1.8</target>
            </configuration>
        </plugin>
    </plugins>
</build>

2. Create a spring configuration file to introduce constraints

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/springbeans.xsd
                           http://www.springframework.org/schema/aop
                           http://www.springframework.org/schema/aop/spring-aop.xsd
                           http://www.springframework.org/schema/context
                           http://www.springframework.org/schema/context/spring-context.xsd">
<!--stay beans Introduced in label AOP and context constraint-->
</beans>

3. Create core business class
Interface

package com.cave.spring.service;

public interface UserService {
    void insertUser(String name);
    void updateUser(String name);
    String findUserById(int id);
    void deleteUserById(int id);
}

realization

package com.cave.spring.service;

import org.springframework.stereotype.Component;

@Component
public class UserServiceImpl implements UserService{
    @Override
    public void insertUser(String name) {
        System.out.println("Insert operation");
    }

    @Override
    public void updateUser(String name) {
        System.out.println("Modify operation");
    }

    @Override
    public String findUserById(int id) {
        System.out.println("Query operation");
//        String str = null;
//        str.indexOf(100);
        return "Return value:Query complete";
    }

    @Override
    public void deleteUserById(int id) {
        System.out.println("Delete operation");
    }
}

4. Define section class

package com.cave.spring.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

@Component
@Aspect
public class MyAspect {
    /**
     * Pointcut Annotations represent pointcut expressions, and methods are generally declared private
     * Other notifications can be called directly in value through the method name
     */
    @Pointcut("execution(* com.cave.spring.service.*.*(..))")
    private void pointCut(){

    }
    //Pre notification: before the introduction of target object method execution
    @Before("pointCut()")
    public void before(JoinPoint jp){//jp refers to the method of the target object to be processed
        System.out.println("Pre notification: executed before the target object method is executed:");
        System.out.println("Intercepted the name of the method to process:");
        String name = jp.getSignature().getName();//The name of the method to process
        System.out.println("Method name:"+name);
        System.out.println("Intercept the parameters of the method to process:");
        Object[] args = jp.getArgs();
        for (Object arg : args){
            System.out.println("Parameters:"+arg);
        }
    }

    //Post notification: after the introduction of the target object method execution, the post notification is executed (the return value of the current method can be obtained)
    @AfterReturning(value = "pointCut()",returning = "result")
    public void afterReturning(Object result){
        System.out.println("Post notification: get the return value of the target object method");
        System.out.println(result);
    }

    //Exception notification: exception notification is executed only when an exception occurs in the method of the target object. On the contrary, if there is no exception, the notification is not executed
    @AfterThrowing(value = "pointCut()",throwing = "ex")
    public void exception(JoinPoint joinPoint,Throwable ex){
        System.out.println(joinPoint.getSignature()+"Method throws an exception");
        System.out.println(ex.getMessage());
    }

    //Surround notification: the notification is executed before and after the method is executed
    // The surround notification carries parameters of type ProceedingJoinPoint. The surround notification is similar to the whole process of dynamic agent
    // A parameter of type ProceedingJoinPoint determines whether to execute the target method
    //The surround notification must have a return value, which is the return value of the target method
    @Around(value = "pointCut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        System.out.println("Around Advice :Execute before target method execution");
        Object proceed = point.proceed();
        System.out.println("Around Advice :Execute after target method execution");
        return proceed;
    }

    //Final notification: the notification of execution after the target method is executed (whether an exception occurs or not)
    @After(value = "pointCut()")
    public void after(){
        System.out.println("Final notice:After the target method is executed(Whether or not an exception occurs)implement");
    }
}

5. In spring Turn on the automatic agent for package scanning and registering aspectj in the XML configuration file

<!--Packet scanning-->
<context:component-scan base-package="com.cave.spring.service,com.cave.spring.aop"></context:component-scan>
<!--Open annotation AOP Use of-->
<aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy>
<!--aop:aspectj-autoproxy The bottom layer is made of AnnotationAwareAspectJAutoProxyCreator Realized,
Is based on AspectJ Annotation adaptation automatic proxy generator.
The working principle is, aop:aspectj-autoproxy Found by scanning@Aspect The defined facet class is found by the facet class according to the pointcut
 To the target method of the target class, and then find the cut in time point by the notification type.-->

6. Testing

public class test01 {
    @Test
    public void test01(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
        UserService userService = (UserService) applicationContext.getBean("userServiceImpl");
        userService.findUserById(100);
    }
}

7. Results

Question import (answer)

1. What is the target?
Target: the object of the method to be enhanced (modified). In enterprises, business class objects are generally used as target objects.

2. How to find the methods that need to be enhanced (modified) in the target object?
breakthrough point

3. How to handle the methods to be enhanced (modified)?
Through Advice and Aspect
Advice: specify the processing method location (PointCut) and the specific processing method
Aspect class: the class where Advice is located is the aspect class

Topics: Java Spring AOP