Introduction: Since the last article covered the core idea of Spring — Ioc (the Spring Ioc Principle) — AOP, the two core ideas of Spring, is certainly not missing either.

So what is AOP? We all know that the core idea of Java is object-oriented OOP, and the core of OOP is encapsulation, inheritance, polymorphism. What is encapsulation?

Encapsulation combines the properties and operations (or services) of an object into a single entity, hiding the internal implementation details of the object as much as possible.

Thus encapsulate the advantage of the whole project in the same business as a separate class/method, makes the same code reusability, this approach can reduce the complexity of the code, but there are some problems, such as we all know that the log is essential to develop logic, when we put the pieces of code and encapsulated into different classes, Once you need to add the log, you need in each class are written to the corresponding logging code, someone will say, can encapsulate the logging code into a class to call, the need to log class invokes the log collection method can, but as a result, the log class and business logic creates coupling, when logging class change, lead to the business logic code needs to be modified. This.. What to do? When OOP fails, AOP comes to the rescue.

AOP: Section-oriented programming, a complement to OOP programming, whose core idea is to dynamically cut code into a specified location of a specified method of a class at runtime.

So it’s easy to solve the problem with AOP thinking. We take the logging logic as an aspect, cut into the specified class/method, and do what we need it to do. Our business logic is neither affected by changes to the logging class nor coupled by its existence.

It’s easy to know the principle, let’s give an example:

For example, most of the time, we need to know the execution time of each API interface, so that we can do performance monitoring and optimization

Here is the general operation:

 1public class Api {
 2    public void test(a){
 3        / /
 4        long begin=(new Date()).getTime();
 5        System.out.println("Start executing....");
 6
 7        // Execute business logic
 8
 9        / / end
10        long end=(new Date()).getTime();
11        // The statistics takes time
12        System.out.println("End execution....");
13        System.out.println("Execution completed, time:"+(end-begin)+"毫秒");
14    }
15}
Copy the code

As you can see, this does get an interface execution time, but the problem is that every method has to add this code, which is very sad.

Let’s use Spring’s AOP to implement the same functionality. First, create a faceted class:

 1package com.test.aoptest;
 2
 3import java.util.Date;
 4
 5import org.aspectj.lang.ProceedingJoinPoint;
 6import org.aspectj.lang.annotation.Around;
 7import org.aspectj.lang.annotation.Aspect;
 8import org.aspectj.lang.annotation.Pointcut;
 9import org.springframework.stereotype.Component;
10import org.springframework.util.StopWatch;
11
12
13@Component
14@Aspect
15public class AopAspect {
16    //within matches method execution within the specified type
17    // Set the pointcut
18    @Pointcut("within(AopService)")
19    // The pointcut signature method is used to connect the annotation to the pointcut.
20    // Find the join point to be cut by interpreting the pointcut expression.
21    // The ultimate goal is to find the connection point that needs to be cut
22    public void pointcut(a){
23        System.out.println("I am pointcut...");
24    }
25// @before: pre-notification that executes the task defined by the notification Before calling the target method
26// @after: a post-notification that executes the task defined in the notification After the execution of the target method, regardless of the result of the execution
27// @after-RETURNING: post-notification, in which tasks defined in the notification are executed After completion of target method execution, if successful
28// @after-throwing: exception notification. If an exception is thrown during the execution of the target method, the task defined by the notification is executed
29// @around: The task defined by the notification needs to be executed both before and after the target method executes
30    @Around("pointcut()")
31    public Object invokeMethod(ProceedingJoinPoint pjp) throws Throwable {
32        / /
33        long begin=(new Date()).getTime();
34        System.out.println("Start executing....");
35        // Execute business logic
36        Object retVal = pjp.proceed();
37        / / end
38        long end=(new Date()).getTime();
39        // The statistics takes time
40        System.out.println("End execution....");
41        System.out.println("Method:"+pjp.getSignature().toShortString()+"Execution completed, time:"+(end-begin)+"毫秒");
42        return retVal;
43    }
44
45}
Copy the code

Second, create a business class:

1package com.test.aoptest;
2import org.springframework.stereotype.Service;
3@Service
4public class AopService {
5    public void test(a){
6        System.out.println("Execute business logic...");
7    }
8}
Copy the code

Next, let’s test:

 1package com.test.aoptest;
 2import javax.annotation.PostConstruct;
 3import org.springframework.beans.factory.annotation.Autowired;
 4import org.springframework.boot.SpringApplication;
 5import org.springframework.boot.autoconfigure.SpringBootApplication;
 6import org.springframework.context.annotation.EnableAspectJAutoProxy;
 7
 8@EnableAspectJAutoProxy / / open the AOP
 9@SpringBootApplication // Inject the startup class into the container
10public class AopTest {
11    @Autowired
12    AopService service;
13    public static void main(String[] args) {
14        SpringApplication.run(AopTest.class, args);
15    }
16    @PostConstruct // Used to perform any initialization on methods that need to be performed after dependency injection is complete
17    public void test(a) {
18        service.test();
19    }
20    @PostConstruct
21    public void test2(a){
22        service.test();
23    }
24}
Copy the code

Look at the output:

1Start....2Execute business logic...3End....4Method: aopservice.test ()17ms5Start....6Execute business logic...7End....8Method: aopservice.test ()0msCopy the code

As you can clearly see, it is output as expected, whereas our business class does not have any logging code intrusion, and changes to the logging class do not affect the business class, so this is an advantage of AOP. This article just used some popular words to briefly describe the principle of AOP, and use a most common and simple example to analyze and understand AOP, in fact, AOP has a lot of knowledge points and uses, which requires us to learn more and write more.

Find this article helpful? Please share it with more people

Focus on “programming without boundaries” and improve your skills