• 探秘SpringAop(一)_介绍以及使用详解


    常用的编程范式

    AOP 是什么

    • 是一种编程方式,不是编程语言
    • 解决特定问题,不能解决所有的问题
    • OOP的补充,不是代替

    AOP 初衷

    • DRY: Don't repeat yourself(代码重复)
    • SoC:Separation of Concerns(关注点分离)
      • 水平分离:展示层-> 服务层 -> 持久层
      • 垂直分离:模块划分(订单、库存等)
      • 切面分离:分离功能性需求与非功能性需求

    AOP的优点

    • 集中处理某一关注点/横切逻辑
    • 可以很方便地添加/删除关注点
    • 侵入性少,增强代码可读性及可维护性

    AOP的应用场景

    • 权限控制
    • 缓存控制
    • 性能监控
    • ...

    支持AOP的语言

    • Java、Python、PHP...

    SpringAOP使用详解

    首先,我整理了一张图,让大家更好的梳理SpringAOP的使用

    @Poincut 详解

    匹配包/类型_ within()
    • 匹配ProductService类里头的所有方法

    • @Pointcut("within(com.zhb.service.ProductService)")

    • 匹配com.zhb包及子包下所有类的方法

    • @Pointcut("within(com.zhb..*)")

    匹配对象
    • 匹配AOP对象的目标对象为指定类型的方法,即LogService的aop代理对象的方法

    • @Pointcut("this(com.zhb.log.Loggable)")

    • 匹配实现Loggable接口的目标对象(而不是aop代理后的对象)的方法

    • @Pointcut("target(com.zhb.log.Loggable)")

    • this 可以拦截 DeclareParents(Introduction)

    • target 不拦截 DeclareParents(Introduction)

    • 匹配所有以Service结尾的bean里头的方法

    • @Pointcut("bean(*Service)")

    匹配参数 args()
    • 匹配任何以find开头而且只有一个Long参数的方法

    • @Pointcut("execution(* ..find(Long))")

    • 匹配任何以find开头的而且第一个参数为Long型的方法

    • @Pointcut("execution(* ..find(Long,..))")

    • 匹配任何只有一个Long参数的方法

    • @Pointcut("within(com.zhb..*) && args(Long)")

    • 匹配第一个参数为Long型的方法

    • @Pointcut("within(com.zhb..*) && args(Long,..)")

    匹配注解
    • 匹配方法标注有AdminOnly的注解的方法
    • @Pointcut("@annotation(com.zhb.anno.AdminOnly) && within(com.zhb..*)")
    • 匹配标注有NeedSecured的类底下的方法 //class级别
    • @Pointcut("@within(com.zhb.anno.NeedSecured) && within(com.zhb..*)")
    • 匹配标注有NeedSecured的类及其子类的方法 //runtime级别
    • 在spring context的环境下,二者没有区别
    • @Pointcut("@target(com.zhb.anno.NeedSecured) && within(com.zhb..*)")
    • 匹配传入的参数类标注有Repository注解的方法
    • @Pointcut("@args(com.zhb.anno.NeedSecured) && within(com.zhb..*)")
    匹配方法
    • 匹配任何公共方法

    • @Pointcut("execution(public * com.zhb.service..(..))")

    • 匹配com.zhb包及子包下Service类中无参方法

    • @Pointcut("execution(* com.zhb..Service.())")

    • 匹配com.zhb包及子包下Service类中的任何只有一个参数的方法

    • @Pointcut("execution(* com.zhb..Service.(*))")

    • 匹配com.zhb包及子包下任何类的任何方法

    • @Pointcut("execution(* com.zhb...(..))")

    • 匹配com.zhb包及子包下返回值为String的任何方法

    • @Pointcut("execution(String com.zhb...(..))")

    • 匹配异常

    • execution(public * com.zhb.service..(..) throws java.lang.IllegalAccessException)

    其实,这么多实际工作中用到的比较少,我平时就用过execution 这一个。

    Advice 详解

    • @Before(value = "matchLongArg() && args(productId)")
    • public void beforeWithArgs(Long productId)
    • @AfterReturning(value = "matchReturn()",returning = "returnValue")
    • public void getReulst(Object returnValue)

    给出一段常用代码

    
        @Pointcut("within(com.zhb.controller.GirlController)")
        public void mathType(){}
    
        @Before(value = "mathType() && args(obj)")
        public void before(Object obj){
    
            System.out.println("这里是目标方法执行前先执行");
            //获取参数
            System.out.println("这里是目标方法的参数"+obj.toString());
        }
        @AfterReturning(returning = "entity",value = "mathType()")
        public void after(JoinPoint joinPoint,Object entity){
            System.out.println("这里是目标方法执行完并成功返回结果 正常结束后才执行");
            System.out.println("方法的返回结果为"+entity);
            System.out.println("目标方法内的参数为"+ Arrays.asList(joinPoint.getArgs()));
        }
        @AfterThrowing(throwing = "e",value = "mathType()")
        public void mathThrow(Throwable  e){
            System.out.println("这里是目标方法抛出异常后才执行");
            System.out.println("异常信息为"+e);
        }
    
    

    大家再用到的时候可以自行搜索

  • 相关阅读:
    HTML5 新增元素梳理
    HTML布局梳理
    ES6中新增let命令使用方法
    xml学习-语法规则
    初步了解URL
    JavaScript——装饰者模式
    移动视频技术——新增API可手工修正视频方向
    如何在移动视频开发中使用ip组播技术
    Windows平台AnyChat视频显示
    如何实现音频合成立体声录制?
  • 原文地址:https://www.cnblogs.com/zhenghengbin/p/9326917.html
Copyright © 2020-2023  润新知