If there is no aop, when doing log processing, we will add log processing in each method, such as
But the processing code is the same in most days. In order to realize code reuse, we may separate log processing into a new method. However, we still have to insert these methods manually.
But these two methods are strongly coupled. If we don't need this function at this time, or want to change to other functions, we must modify them one by one.
Through the dynamic agent, the corresponding process can be executed at the specified location. In this way, some horizontal functions can be pulled out to form an independent module, and then these functions can be inserted at the specified position. This idea is called aspect oriented programming, or AOP.
In order to perform these horizontal functions at the specified location, you need to know where to specify
For example, in the above figure, the aop implementation at the method level refers to method2 as the tangent point in a program execution chain, that is, the crosscutting function will be executed during the execution of method2. What will be executed before or after method2? These are specified by advice. There are five types of advice:
Notification type | brief introduction |
---|---|
Before (advance notice) | Execute before target method call |
After (post notification) | Execute after target method call |
After returning | Execute after the target method is successfully executed |
After throwing (exception notification) | Execute after the target method throws an exception |
Around (surround notification) | It is equivalent to combining pre and post |
Combining pointcuts and notifications is a facet, which specifies when, where and what methods to perform. This aspect is defined in spring aop as follows:
@Aspect @Component public class UserAspect { @Before("execution(* com.aop.service.impl.UserServiceImpl.login(..))") public void loginLog(){ System.out.println("user login"); } }
Use the annotation @ Aspect to declare a specific class as a facet, so that the methods under the class can be declared as horizontal function points and inserted into the specified location. Use the execution expression to declare at this pointcut. The format is as follows
The first position specifies the return value of the method. The * sign represents the return value of any type, followed by the class and method name. The * sign also represents any, which is any method in the class. In the previous example, the method name is login, which specifies the login method in the class. Then the last parameter is the method input parameter. Because overloading is supported in java, this parameter can help you locate more accurately. Two points represent any parameter type. In this way, the execution expression tells the program where to execute the notification. The method modified by annotations such as @ Before is the content of the notification, that is, what to do.
At this point, we can use spring aop, but there are two points to note
Declare the facet class as a bean
The class of the method specified by the pointcut also needs to be injected by spring to take effect
Original text: https://blog.csdn.net/baidu_33403616/article/details/70304051
Control layer code:
GetMapping( "/hello1") public String hello1(@RequestParam( "name" ) String name , @RequestParam("age")String age) { return "hello "+name+"age="+age; }
Section class code:
public class MyAdvice{ private Logger logger = LoggerFactory.getLogger(MyAdvie.class); //Define section @Pointcut(value = "execution( * com.quanfon.spring.aop.controller.*.*(..))") public void myPointcut(){ } @Around( "myPointcut()") public 0bject myLogger(ProceedingJoinPoint pjp) throws Throwable { String className = pjp.getTarget().getclass().toString(); String methodName = pjp.getSignature().getName(); 0bject[] array = pjp.getArgs(); 0bjectMapper mapper = new 0bjectMapper(; logger.info("Before calling:"+className+" : "+methodName+"The parameter passed is."+mapper.writeValueAsString(array)); object obj = pjp.proceed(); logger.info("After call:"+className+ " : "+methodName+"Return value."+mapper.writeValueAsString(obj)); return obj; } }
After starting spring boot, the browser accesses localhost: 8080 / hello1? name=kkkk&age=10
View the results returned by the console: