SpringBoot Series: Common Annotations summary of AOP-related notes

Disclaimer: This article is a blogger original article, follow the CC 4.0 BY-SA copyright agreement, reproduced, please attach the original source link and this statement.
This link: https://blog.csdn.net/mu_wind/article/details/102758005

1 AOP Introduction

AOP (Aspect Oriented Programming) is the aspect-oriented programming, which programming idea is to spread a different but functionally identical service code extracted out from the business logic, packaged as separate modules, these modules are called independent section, the section specific function method is called concerns. In the course of the business logic implementation, AOP will separate the facets and concerns dynamic cut into business processes, the benefits of doing so is to increase the reusability and maintainability function code.

With real examples, for example, a company will have a lot of relatively independent departments, are responsible for some of the services, such as technical department is responsible for technology development, market operations department is responsible for market development, human resources personnel in charge of the company, each department can view as an aspect. If the project business expansion, adding new section, opening new departments similar companies. Thus, the program can be configured to form a pluggable program structure.

The AOP process 2 SpringBoot

2.1 AOP environment

Use AOP, we first need to introduce rely on AOP.

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

2.2 AOP implementation section

If we want to print some Log, after the introduction of the above dependence, we create a new class LogAspectHandler, and a processing method used to define the cut surface in the project Just add a class on @Aspect annotation can be. @Aspect annotation is used to describe a class section, the definition section of the class when needed Applying this comment. @Component annotation on the class to Spring to manage.

@Aspect
@Component
public class LogAspectHandler {

}

2.3 Common Notes

Here are a few notes and use common.

2.3.1 @Pointcut

@Pointcut annotation to define a section that interest above the entrance of something, the entry point defines an event trigger time.

@Aspect
@Component
public class LogAspectHandler {

    /**
     * 定义一个切面,拦截 com.itcodai.course09.controller 包和子包下的所有方法
     */
    @Pointcut("execution(* com.mutest.controller..*.*(..))")
    public void pointCut() {}
}

@Pointcut annotation specifies a section, the definition needs to intercept things, presented here two commonly used expressions: One is to use execution (), and the other is to use annotation ().
execution expression:

To Execution (* com.mutest.controller ... . (...))) expression, for example:

  • * A first position number: indicates the type of the return value, * denotes all types. Package name: indicates the need to intercept the package name, the latter two periods represents the current sub-packet and a current packet of all packets, all classes in the present embodiment the method of the middle finger bag com.mutest.controller, subpackages.
  • * Number of second position: that the class name, * represents all classes. (...): This asterisk indicates the method name, represents all the way back inside the parentheses represents the parameters of the method, two periods indicate any parameters.

annotation () expression:

annotation () method is to define a section for notes, for example, we do have a section for the method @PostMapping annotations, you can define the following section:

@Pointcut("@annotation(org.springframework.web.bind.annotation.PostMapping)")
public void annotationPointcut() {}

Then use that section, it would cut into the annotations are all methods of @PostMapping. This embodiment is suitable for processing @ GetMapping, @ PostMapping, @ DeleteMapping various different annotation processing logic specific scene.

2.3.2 @Before

@Before method specified in the notes section before cutting target method execution, you can do some Log processing, you can do some of the statistical information, such as access to a user's request URL and the user's IP address, etc., to do this in personal sites when they are can be obtained, it is commonly used method. For example the following codes:

@Aspect
@Component
@Slf4j
public class LogAspectHandler {
    /**
     * 在上面定义的切面方法之前执行该方法
     * @param joinPoint jointPoint
     */
    @Before("pointCut()")
    public void doBefore(JoinPoint joinPoint) {
        log.info("====doBefore方法进入了====");

        // 获取签名
        Signature signature = joinPoint.getSignature();
        // 获取切入的包名
        String declaringTypeName = signature.getDeclaringTypeName();
        // 获取即将执行的方法名
        String funcName = signature.getName();
        log.info("即将执行方法为: {},属于{}包", funcName, declaringTypeName);

        // 也可以用来记录一些信息,比如获取请求的 URL 和 IP
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        // 获取请求 URL
        String url = request.getRequestURL().toString();
        // 获取请求 IP
        String ip = request.getRemoteAddr();
        log.info("用户请求的url为:{},ip地址为:{}", url, ip);
    }
}

JointPoint useful for objects that can be used to obtain a signature, the signature may be obtained using the package name in the request, the name of the method, including parameter (() obtained by joinPoint.getArgs) and the like.

2.3.3 @After

@After annotations and notes @Before corresponds to the method specified in section performed after cutting the target method, you can also do some processing after the completion of a Log method.

@Aspect
@Component
@Slf4j
public class LogAspectHandler {
    /**
     * 定义一个切面,拦截 com.mutest.controller 包下的所有方法
     */
    @Pointcut("execution(* com.mutest.controller..*.*(..))")
    public void pointCut() {}

    /**
     * 在上面定义的切面方法之后执行该方法
     * @param joinPoint jointPoint
     */
    @After("pointCut()")
    public void doAfter(JoinPoint joinPoint) {

        log.info("==== doAfter 方法进入了====");
        Signature signature = joinPoint.getSignature();
        String method = signature.getName();
        log.info("方法{}已经执行完", method);
    }
}

Here, we have to write a Controller test results of a new AopController as follows:

@RestController
@RequestMapping("/aop")
public class AopController {

    @GetMapping("/{name}")
    public String testAop(@PathVariable String name) {
        return "Hello " + name;
    }
}

Start the project in the browser, enter: localhost: 8080 / aop / csdn, look at the console output:

====doBefore 方法进入了====  
即将执行方法为: testAop,属于com.itcodai.mutest.AopController包  
用户请求的 url 为:http://localhost:8080/aop/name,ip地址为:0:0:0:0:0:0:0:1  
==== doAfter 方法进入了====  
方法 testAop 已经执行完

Log out from the print can be seen in logic and the program execution sequence, it can be very intuitive grasp the actual role and @Before @After two annotations.

2.3.4 @AfterReturning

@AfterReturning annotations and @After somewhat similar, except that @AfterReturning annotation can be used to capture return value after the cutting method been performed, the return value enhancement process on the business logic, for example:

@Aspect
@Component
@Slf4j
public class LogAspectHandler {
    /**
     * 在上面定义的切面方法返回后执行该方法,可以捕获返回对象或者对返回对象进行增强
     * @param joinPoint joinPoint
     * @param result result
     */
    @AfterReturning(pointcut = "pointCut()", returning = "result")
    public void doAfterReturning(JoinPoint joinPoint, Object result) {

        Signature signature = joinPoint.getSignature();
        String classMethod = signature.getName();
        log.info("方法{}执行完毕,返回参数为:{}", classMethod, result);
        // 实际项目中可以根据业务做具体的返回值增强
        log.info("对返回参数进行业务上的增强:{}", result + "增强版");
    }
}

Note that, in @AfterReturning notes, the value of the property must be consistent returning and parameters, otherwise it will not be detected. The second method is the reference value is returned cutting process may be enhanced return value doAfterReturning method, respective packages can be done according to the service needs. We restart the service, and then test:

方法 testAop 执行完毕,返回参数为:Hello CSDN  
对返回参数进行业务上的增强:Hello CSDN 增强版

2.3.5 @AfterThrowing

When the cutting process is performed in the method throws an exception, the method enters @AfterThrowing annotations performed, in the method can make some exception processing logic. Note that the value of the property must be throwing parameters and consistent, otherwise it will error. The second method is the reference into the thrown exception.

@Aspect
@Component
@Slf4j
public class LogAspectHandler {
    /**
     * 在上面定义的切面方法执行抛异常时,执行该方法
     * @param joinPoint jointPoint
     * @param ex ex
     */
    @AfterThrowing(pointcut = "pointCut()", throwing = "ex")
    public void afterThrowing(JoinPoint joinPoint, Throwable ex) {
        Signature signature = joinPoint.getSignature();
        String method = signature.getName();
        // 处理异常的逻辑
        log.info("执行方法{}出错,异常为:{}", method, ex);
    }
}

Guess you like

Origin blog.csdn.net/mu_wind/article/details/102758005