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: