• springboot中aop的尝试


    我们在项目中如果使用spring的框架的话,aop技术多多少少也接触过,所以打算在这里总结一下AOP的技术核心和常用方法。

    AOP的基本使用方法 --> 全局AOP监听

    我们现在要在Controller层做一个监听,每次进入controller的方法的时候,都启动AOP进行方法检查等操作。

    接下来我们看一下源代码:

    Controller层:

    
    @RestController
    public class PageController {  //这个类在com.demo.controller包下
    @RequestMapping("/hello")
    
       public Map<String,String> helloWorld(){
           Map<String,String > map = new HashMap<>();
    
           System.out.println("代码执行中");
           map.put("hello","world");
           System.out.println("继续执行");
           return map;
       }
    }
    
    

    AOP:

    
    
    /**
     * Created with IntelliJ IDEA.
     * User: WHOAMI
     * Time: 2019 2019/6/2 16:06
     * Description: ://TODO ${END}
     */
    @Slf4j
    @Aspect
    @Component
    public class WebLogAspect {
    
     @Pointcut("execution(public * com.demo.controller.*.*(..))")
        private void weblog(){}
    
        @Before("weblog()")
        private void doBefore(JoinPoint joinPoint) throws Throwable {
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            HttpServletRequest request = attributes.getRequest();
    
            log.info("URL: "+request.getRequestURL().toString());
            log.info("Method" + request.getMethod());
            log.info("HTTP_METHOD: "+request.getMethod());
    
            log.info("IP: "+request.getRemoteAddr());
            Enumeration<String> enu = request.getParameterNames();
            while (enu.hasMoreElements()) {
                String name = enu.nextElement();
                log.info("name:{},value:{}", name, request.getParameter(name));
            }
        }
    
        @AfterReturning(returning = "ret", pointcut = "weblog()")
        public void doAfterReturning(Object ret) throws Throwable {
            log.info("RESPONSE: " + ret);
        }
    }
    
    
    • 下面讲解一下这个AOP的常用技术

    @Aspect
    标记这是一个切面,如果没有这个注解,那么这个方法不启动

    Pointcut
    切点,后面的execution是决定监听哪里的方法

    Befoe
    前置通知

    After
    后置通知

    下面是我常用的AOP方法

    利用自定义注解决定切点

    下面我们自定义一个注解

    @Target(ElementType.METHOD)
    @Documented
    @Inherited
    @Retention(RetentionPolicy.RUNTIME)
    public @interface Cache {
      boolean ifDelete() default false;
    }
    
    

    在我们的Controller层方法上加入这个注解

    
    @RequestMapping("/hello")
       @Cache(ifDelete = true)
       public Map<String,String> helloWorld(){
           Map<String,String > map = new HashMap<>();
    
           System.out.println("代码执行中");
           map.put("hello","world");
           System.out.println("继续执行");
           return map;
       }
    
    

    AOP层:

    
    @Slf4j
    @Aspect
    @Component
    public class TestAsp {
    
        @Around("@annotation(com.demo.flag.Cache)")
        public Object testJoinPoint(ProceedingJoinPoint joinPoint) throws Throwable {
    
            System.out.println("进入aop");
    
            return joinPoint.proceed();
            System.out.println("代码执行aop后");
        }
    }
    
    

    我们访问一下这个地址,结果是这个样子的

    >进入aop
    >代码执行中
    >继续执行
    >代码执行aop后
    

    这里不需要PointCut,而是利用@annotation将所有有上面这个注解的方法都会进入这个AOP方法。

    其实这个@Around是一个环绕通知,你可以在这里通过jionPoint获得到访问者IP,变量参数等等。

    这个joinPoint.proceed()方法是让controller方法的必要条件。

    joinPoint.proceed()方法后的代码是处理完方法后需要执行的代码,这样就可以想象成这个Around将controller层的某个方法'包裹'起来了。

    JoinPoint的常用方法

    • 获取到方法的注解
    MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
    
            Cache annotation = methodSignature.getMethod().getAnnotation(Cache.class);
    
  • 相关阅读:
    P1242 新汉诺塔(hanio)
    P2878 [USACO07JAN]保护花朵Protecting the Flowers
    P2096 最佳旅游线路
    [P1363] 幻想迷宫
    在矩阵上跑最小生成树
    tarjan+topsort
    tarjan缩点
    【P3398]】仓鼠找sugar
    树形数组暴力
    解决跨域问题
  • 原文地址:https://www.cnblogs.com/adroitwolf/p/14310213.html
Copyright © 2020-2023  润新知