AOP implementations use custom annotation

Foreword

Recently, a new demand, is certain operations the user to monitor the operation record to be written to the database, first thought of Interceptor (Interceptor) using filters and Filter Spring, both of which require complex configuration (can to solve the problem is by no means the code to get started), and then brainstorm to start based annotation achieve AOP, in the Action to be monitored together with the notes, perfect!

Writing custom annotations

package com.asiainfo.annotation;

import java.lang.annotation.*;

/**
 * @description: 自动以注解
 * @author: Mr-box
 * @create: 2019-05-23 10:00
 **/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented

public @interface EagleEye {

    String desc() default "";

}
复制代码
  • The life cycle is defined annotations running
  • Annotations to define the role of a method
  • Mark JavaDoc annotation can be recorded
  • Annotated as defined EagleEye (Hawkeye)
  • Defined desc, is used to describe a modified method of

AOP definitions section

package com.asiainfo.aspect;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;

/**
 * @description: 定义AOP切面
 * @author: Mr-box
 * @create: 2019-05-23 10:00
 **/

@Aspect
@Component
public class LogAspect {

    // 定义切点
    @Pointcut("@annotation(com.asiainfo.annotation.EagleEye)")
    public void eagleEye() {

    }

    // 利用环绕增强来实现我们的功能
    @Around("eagleEye()")
    public Object surroundInform(ProceedingJoinPoint proceedingJoinPoint) {

        System.out.println("环绕通知开始...");
        
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();

        System.out.println("请求路径 : " + request.getRequestURL());
        System.out.println("请求方式 : " + request.getMethod());
        System.out.println("方法名 : " + proceedingJoinPoint.getSignature().getName());
        System.out.println("类路径 : " + proceedingJoinPoint.getSignature().getDeclaringTypeName());
        System.out.println("参数 : " + Arrays.toString(proceedingJoinPoint.getArgs()));
        
        try {
            // 真实业务代码,这里是伪代码
            Object o =  proceedingJoinPoint.proceed();
            System.out.println("方法环绕proceed,结果是 :" + o);
            return o;
        } catch (Throwable e) {
            e.printStackTrace();
            return null;
        }
    }
}
复制代码

Use annotations

  • @EagleEye added in method (desc = "test interface") can be realized annotations
package com.asiainfo.action;

import com.asiainfo.annotation.EagleEye;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @description: 定义AOP切面
 * @author: Mr-box
 * @create: 2019-05-23 10:00
 **/
 
@RestController
public class TestAction {

    @EagleEye(desc = "测试接口")
    @RequestMapping(value = "/sayHello")
    public String test(String params)throws Exception{
        System.out.println("参数:" + params);
        return "hello "+ params;
    }
}
复制代码

Start the test

The browser calls: http://127.0.0.1:8081/aop-demo/sayHello?params=lala observation log output:


  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.2.5.RELEASE)

2019-05-23 10:00  INFO 3183 --- [           main] com.asiainfo.SpringAopDemoApplication    : Starting SpringAopDemoApplication on zhangdsdeiMac.local with PID 3183 (/Users/zhangds/Development/code/spring-aop-demo/target/classes started by zhangds in /Users/zhangds/Development/code/spring-aop-demo)
2019-05-23 10:00  INFO 3183 --- [           main] com.asiainfo.SpringAopDemoApplication    : No active profile set, falling back to default profiles: default
2019-05-23 10:00  INFO 3183 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8081 (http)
2019-05-23 10:00  INFO 3183 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2019-05-23 10:00  INFO 3183 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.31]
2019-05-23 10:00  INFO 3183 --- [           main] o.a.c.c.C.[.[localhost].[/aop-demo]      : Initializing Spring embedded WebApplicationContext
2019-05-23 10:00  INFO 3183 --- [           main] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 627 ms
2019-05-23 10:00  INFO 3183 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
2019-05-23 10:00  INFO 3183 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8081 (http) with context path '/aop-demo'
2019-05-23 10:00  INFO 3183 --- [           main] com.asiainfo.SpringAopDemoApplication    : Started SpringAopDemoApplication in 1.115 seconds (JVM running for 1.654)
2019-05-23 10:00  INFO 3183 --- [nio-8081-exec-1] o.a.c.c.C.[.[localhost].[/aop-demo]      : Initializing Spring DispatcherServlet 'dispatcherServlet'
2019-05-23 10:00  INFO 3183 --- [nio-8081-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2019-05-23 10:00  INFO 3183 --- [nio-8081-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 4 ms
请求路径 : http://127.0.0.1:8081/aop-demo/sayHello
请求方式 : GET
方法名 : test
类路径 : com.asiainfo.action.TestAction
参数 : [lala]
环绕通知开始...
参数:lala
方法环绕proceed,结果是 :hello lala
复制代码

to sum up

  • Configuring than the cut-off point flexibility with higher expression execution, execution expression has certain limitations.
  • Custom annotation flexibility is relatively high, but this is only a small custom annotation usage only.

Guess you like

Origin juejin.im/post/5e742d69f265da575e37d43e