Aop [aspect oriented programming]

1 what is aop

aop is a technology to realize the unified maintenance of program functions through precompiled mode and runtime dynamic agent. aop, also known as aspect oriented programming, is the continuation of oop. It is not only a hot spot in software development, but also an important content in spring framework. It is a derivative generic of functional programming. aop can isolate each part of business logic, reduce the coupling degree of each part, improve the reusability of program, and improve the efficiency of development.

2 business scenario

Reference blog: Explain Spring in detail - AOP details (AOP overview)_ Lala blog - CSDN blog_ aop

We may use the same code logic in different methods. For example: logging, performance statistics, security control, transaction processing, exception handling.

We can use several pictures to express the following (the above blog thinks the pictures are more intuitive):

It can be seen from the above figure that when we implement different functions, the same code logic is used in the middle. If we are not afraid of trouble, method 1: call the logic for each method call, and the result can be completed, but a large amount of redundant code will be generated.

Method 2: extract the general code logic, and execute the method when there is a method call. This method has a certain improvement over method 1.

Method 3: inject the method into a certain place of access


3 related terms in AOP

Join point: a point that is clearly defined in a program, typically including method calls, access to class members, and execution of exception handling program blocks

Pointcut: each program has many connection points, that is, the connection point is an objective thing in the program class. aop locates a specific connection point through the "pointcut". The join point is equivalent to the record in the database, and the tangent point is equivalent to the condition of querying the data in the database. Tangent point and connection point are a one to many relationship. We can locate multiple connection points with one tangent point.

Advice: advice defines the specific operations to be performed by defining program points in pointcut. It distinguishes between before, after and around each joint point or instead of the executed code

Aspect: the aspect is composed of tangent point and enhancement. It includes both the definition of crosscutting logic and the definition of connection point. springAop is the framework responsible for implementing the aspect. It weaves the crosscutting logic defined by the aspect into the connection point specified by the aspect

Introduction: introduction is a special enhancement that adds some properties and methods to a class. In this way, even if a business class does not implement an interface originally, through the introduction function of aop, we can dynamically add the implementation logic of the interface to the business class to make the business class become the implementation class of the interface

Target: the woven in target class of enhanced logic. Without aop, the target business class needs to implement all logic. With the help of aop, the target business class only needs to implement the program logic of non crosscutting logic, while the crosscutting logic such as performance monitoring and transaction management can be dynamically woven into a specific connection point using aop

Weaving: weaving is the process of adding enhancements to the target connection point. aop is like a loom that weaves together target classes, enhancements, or introductions through aop. According to different weaving requirements, aop has three weaving methods

A: compile time weaving, which requires the use of a special Java compiler

b: class loading period weaving, which requires the use of special class loaders

c: dynamic proxy weaving, adding an enhanced subclass generation method for the target class at run time

spring uses dynamic proxy weaving, while AspectJ uses compiler weaving and class loader weaving

Referring to the above blog, we can understand the above concepts according to examples in life:

Once a senior high school science class 4 had a thorough examination. After the examination results came down, the results were good and bad. The head teacher decided to have a psychological conversation with the students with a total score of less than 500 points to promote their learning progress.

We can make a simple analogy:

JoinPoint enables all students in our science class 4 to be talked about

The Pointcut point is the point we find according to the characteristics, that is, 500 points

Advice enhancement is what we want to do, that is, psychological conversation

aspect is a combination of our pointcuts and enhancements

4 code example

Step 1: create a project and introduce corresponding dependencies

Step 2: define the business logic class mainlogic java

Step 3: define the facet class mainaspect java

Step 4: add the business logic class and aspect class to the container mainconfigaaop java

Step 5: Test

Step 1: create a project and introduce corresponding dependencies

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>org.example</groupId>
  <artifactId>aop</artifactId>
  <version>1.0-SNAPSHOT</version>

  <name>aop</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.1.5.RELEASE</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aspects</artifactId>
      <version>5.1.5.RELEASE</version>
    </dependency>
  </dependencies>
</project>

Step 2: define the business logic class mainlogic java

public class MainLogic {

    public int calculation(int a,int b){
        System.out.println("**********Enter the main business logic class************");
        int c = a/b;
        return c;
    }

    public int calculationNo(int a,int b){
        System.out.println("**********Test to see if this business class cuts in************");
        int c = a/b;
        return c;
    }

}

Step 3: define the facet class mainaspect java

@Aspect
public class MainAspect {



    /**
     * Define pointcut expressions that are common to pointcut extraction
     * @Pointcut("execution(public int com.liubujun.aop.MainLogic.*(..))")Represents all methods in the MainLogic class
     * @Pointcut("execution(public int com.liubujun.aop.MainLogic.calculation(int,int))") Indicates that there are only calculation methods in MainLogic
     */
    @Pointcut("execution(public int com.liubujun.aop.MainLogic.*(..))")
    private void pointCutCommon(){};



    /**
     * Before the target method; Pointcut expression (specify which method to cut in)
     * joinPoint.getSignature().getName() Know which method is called
     * Arrays.toString(joinPoint.getArgs()) The parameters of the method call are printed out
     * @param joinPoint
     */
    @Before(value = "pointCutCommon()")
    public void logStart(JoinPoint joinPoint){
        System.out.println("Start>>>>>>>"+joinPoint.getSignature().getName()+">>>>>"+ Arrays.toString(joinPoint.getArgs()));
    }

    @After(value = "com.liubujun.aop.MainAspect.pointCutCommon()")
    public void logAfter(JoinPoint joinPoint){
        System.out.println("After>>>>>>>"+joinPoint.getSignature().getName()+">>>>>"+ Arrays.toString(joinPoint.getArgs()));
    }

    /**
     * Use return to receive the return value
     * @param object
     */
    @AfterReturning(value = "pointCutCommon()",returning = "object")
    public void logReturn(Object object){
        System.out.println("AfterReturning>>>>>>>Return results"+object);
    }

    /**
     * Use throw to receive exceptions
     * @param joinPoint This parameter comes first
     * @param e
     */
    @AfterThrowing(value = "execution(public int com.liubujun.aop.MainLogic.*(..))",throwing = "e")
    public void logException(JoinPoint joinPoint,Exception e){
        System.out.println("AfterThrowing>>>>>>>"+joinPoint.getSignature().getName()+">>>>>Abnormal information{"+ e.getStackTrace()+"}");
    }


}

Step 4: add the business logic class and aspect class to the container mainconfigaaop java

@EnableAspectJAutoProxy
@Configuration
public class MainConfigAop {


    /**
     * The logical class cuts into the container
     * @return
     */
    @Bean
    public MainLogic mainLogic(){
        return new MainLogic();
    }


    /**
     * Cut the facet class into the container
     * @return
     */
    @Bean
    public MainAspect mainAspect(){
        return new MainAspect();
    }
}

Step 5: Test 1 (throw exception)

public class AppTest {


    @Test
    public void testAop(){
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigAop.class);
        MainLogic mainLogic = applicationContext.getBean(MainLogic.class);
        mainLogic.calculation(10,0);
        applicationContext.close();
    }
}

Operation results:

Step 5: Test 2 (normal return)

public class AppTest {


    @Test
    public void testAop(){
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigAop.class);
        MainLogic mainLogic = applicationContext.getBean(MainLogic.class);
        mainLogic.calculation(10,2);
        applicationContext.close();
    }
}

Operation results:

Keywords: linq p2p GNU

Added by haku87 on Sun, 12 Dec 2021 13:27:15 +0200