交流群:462197261站长百科站长论坛热门标签收藏本站北冥有鱼 互联网前沿资源第一站 助力全行业互联网+
点击这里给我发消息
  • 当前位置:
  • Spring AOP注解案例及基本原理详解

    北冥有鱼 教程大全 2020-06-28 ,,

    切面:Aspect

    切面=切入点+通知。在老的spring版本中通常用xml配置,现在通常是一个类带上@Aspect注解。切面负责将 横切逻辑(通知) 编织 到指定的连接点中。

    目标对象:Target

    将要被增强的对象。

    连接点:JoinPoint

    可以被拦截到的程序执行点,在spring中就是类中的方法。

    切入点:PointCut

    需要执行拦截的方法,也就是具体实施了横切逻辑的方法。切入点的规则在spring中通过AspectJ pointcut expression language来描述。

    切入点与连接点的区别:连接点是所有可以被"切"的点;切入点是真正要切的点。

    通知:Advice

    针对切入点的横切逻辑,包含“around”、“before”和“after”等不同类型的通知。

    通知的作用点如其命名:

    • before:在切入点之前执行
    • after:在切入点之后执行
    • around:在切入点拦截方法,自定义前后,更灵活

    还有一些异常处理的通知,这里不一一举例

    织入:Weaving

    将切面和目标对象连接起来,创建代理对象的过程。spring中用的是动态代理。假如目标对象有接口,使用jdk动态代理;否则使用cglib动态代理。

    说了这么多概念,看看代码实现可能会使读者理解的更深刻一些,这里简单写一个通过注解增强方法的AOP-Demo。
    首先是切面类:

    package com.example.demo.aop;
    
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.*;
    import org.springframework.stereotype.Component;
    
    /**
     * @author Fcb
     * @date 2020/6/20
     * @description 切面类=切入点+通知
     */
    @Aspect
    @Component
    public class LogAspect {
    
      //这个方法定义了切入点
      @Pointcut("@annotation(com.example.demo.aop.anno.MyLog)")
      public void pointCut() {}
    
      //这个方法定义了具体的通知
      @After("pointCut()")
      public void recordRequestParam(JoinPoint joinPoint) {
        for (Object s : joinPoint.getArgs()) {
          //打印所有参数,实际中就是记录日志了
          System.out.println("after advice : " + s);
        }
      }
    
      //这个方法定义了具体的通知
      @Before("pointCut()")
      public void startRecord(JoinPoint joinPoint) {
        for (Object s : joinPoint.getArgs()) {
          //打印所有参数
          System.out.println("before advice : " + s);
        }
      }
    
      //这个方法定义了具体的通知
      @Around("pointCut()")
      public Object aroundRecord(ProceedingJoinPoint pjp) throws Throwable {
        for (Object s : pjp.getArgs()) {
          //打印所有参数
          System.out.println("around advice : " + s);
        }
        return pjp.proceed();
      }
    }

    注解:

    package com.example.demo.aop.anno;
    import java.lang.annotation.*;
    /**
     * @author Fcb
     * @date 2020/6/20
     * @description
     */
    @Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.METHOD, ElementType.TYPE})
    public @interface MyLog {
    }

    目标类:

    package com.example.demo.aop.target;
    
    import com.example.demo.aop.anno.MyLog;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.RestController;
    
    /**
     * @author Fcb
     * @date 2020/6/20
     * @description
     */
    @RestController
    public class MockController {
    
      @RequestMapping("/hello")
      @MyLog
      public String helloAop(@RequestParam String key) {
        System.out.println("do something...");
        return "hello world";
      }
    
    }

    最后是测试类:

    package com.example.demo.aop.target;
    
    import org.junit.jupiter.api.Test;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    /**
     * @author Fcb
     * @date 2020/6/20
     * @description
     */
    @SpringBootTest
    class MockControllerTest {
      @Autowired
      MockController mockController;
    
      @Test
      void helloAop() {
        mockController.helloAop("aop");
      }
    }

    控制台结果:

    around advice : aop
    before advice : aop
    do something...
    after advice : aop

    以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持北冥有鱼。


    广而告之:
    热门推荐:
    js form表单input框限制20个字符,10个汉字代码实例

    直接粘贴到html文件便可看到效果 <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> ···

    简单实现jQuery进度条轮播实例代码

    本文实例为大家分享了jQuery进度条轮播的具体实现代码,供大家参考,具体内容如下  HTML:  <div class="bannar"> <div class="img"> <ul> <li style="background:url(img/1.jpg);display:block;"></li> ···

    浅谈利用缓存来优化HTML5 Canvas程序的性能

    canvas玩多了后,就会自动的要开始考虑性能问题了。怎么优化canvas的动画呢?   【使用缓存】   使用缓存也就是用离屏canvas进行预渲染了,原理很简单,就是先绘制到一个离屏canvas中,然后再通过drawImage把离屏canvas画到主canvas中。可能看到这很多人就会误解,这不是写···

    MySql带OR关键字的多条件查询语句

    上篇文章给大家介绍了Mysql带And关键字的多条件查询语句,下面给大家介绍MySql带OR关键字的多条件查询语句,感兴趣的朋友可以一起学习。 MySQL带OR关键字的多条件查询,与AND关键字不同,OR关键字,只要记录满足任意一个条件,就会被查询出来。 SELECT * | {字段名1,字段名2···

    Java数据类型与MySql数据类型对照表

    本文讲述了Java数据类型与MySql数据类型对照表。分享给大家供大家参考,具体如下: 类型名称 显示长度 数据库类型 JAVA类型 JDBC类型索引(int) VARCHAR L+N VARCHAR java.lang.String 12 CHAR N CHAR java.lang.String 1 BLOB L+N BLOB java.lang.byte[] -4 TEXT 6···

    JavaScript for循环 if判断语句(学习笔记)

    今天学习了JavaScript里面的for循环以及if的判断语句 for(初始值;循环条件;操作){   满足条件要执行的代码语句 } 初始值:循环前的初始化变量,通常为赋值表达式:建议用var赋值,可以加快运行速度。 循环条件:每次循环前要计算的条件,是运算符类别中的条件运算符,返回···

    在localStorage中存储对象数组并读取的方法

    频繁ajax请求导致页面响应变慢。于是考虑将数据存储在window.storage中,这样只请求一次ajax,而不需要频繁请求。 鉴于localstorage中只能存储字符串,所以我们要借助于JSON.stringify()和JSON.parse(); $.ajax({ type: "get", async: "true", url: "", data: {}, dataType: "···

    Vue.js:使用Vue-Router 2实现路由功能介绍

    注意:vue-router 2只适用于Vue2.x版本,下面我们是基于vue2.0讲的如何使用vue-router 2实现路由功能。 推荐使用npm安装。 npm install vue-router 一、使用路由 在main.js中,需要明确安装路由功能: import Vue from 'vue' import VueRouter from 'vue-router' import A···

    一些不错的JS 自定义函数第1/2页

    1、dayin()作用:将id为dayin的内容,新建页面并打印,可解决打印某页面中的部分内容的问题。使用方法:将要打印的内容通过 <span id="dayin"></span>包含起来,然后在某个按扭中定义事件<input type="button" onclick="dayin()" value="打印">复制代···

    提高PHP编程效率的方法

    1、如果能将类的方法定义成static,就尽量定义成static,它的速度会提升将近4倍。2、$row['id'] 的速度是$row[id]的7倍。3、echo 比 print 快,并且使用echo的多重参数(译注:指用逗号而不是句点)代替字符串连接,比如echo $str1,$str2。4、在执行for循环之前确定最大···