aop学习笔记之Pointcut Express和Advice(二)

aop学习笔记之基于@Aspect的AOP实现:http://blog.csdn.net/zyb2017/article/details/79420172
本篇代码下载地址:https://download.csdn.net/download/zyb2017/10277492

前言

在写上一篇的时候在想Aop的适用场景,那Aop到底在做怎样一件事情呢?

一 Pointcut Express

Aop的使用我理解主要分为两大部分PointcutExpress(切面表达式)和Advice,前者表明了切入点,后者描述了切入时机
这里写图片描述

看到这里我们就了解了,Aop就好像一个插队的过程,PointcutExpress描述了要插到哪里,Advice则指出了插到这个人的前面去搞事情还是到他后面去搞事情

Pointcut Express又由designators(指示器),wildcards(通配符),operators(运算符)组成

这里写图片描述

二 wildcards

运算符我们就不说了,先说wildcards这个通配符,包含三种如下:

符号作用
*匹配任意数量字符
+匹配自定类及其子类
..匹配任意数的子包或参数

例如:com.TranisentBa.Demo.Service.*

三 designators

指示器的分类有很多种,之前看过一个视频按照匹配的目标分类如下:

这里写图片描述

3.1 within

开始测试之前先描述下环境,一个ProductService中的delete方法,应用Aop在该方法执行前做一次校验,如果不是管理员,则抛出异常。启动入口如下:

    //处理异常
    @Test(expected = Exception.class)
    public void annoDeletetTrst() {
    //正常管理员为admin
        CurrentUserHolder.set("tom");
        productService.delete(1L);
    }
    /**within匹配类**/
    @Pointcut("within(com.march.aop.service.ProductService)")
    public void matchWinth(){}

    @Before("matchWinth()")
    public void before(){
        System.out.println("###within ");
        authService.checkAccess();
    }

3.2 this

this匹配的是经过aop代理之后的类 通过introduction动态添加的方法也可以匹配到

    /**this**/
    @Pointcut("this(com.march.aop.service.ProductService)")
    public void matchThis(){}

    @Before("matchThis()")
    public void beforeThis(){
        System.out.println("###this ");
        authService.checkAccess();
    }

3.3 target

target匹配的是原目标对象而非代理对象 通过introduction添加的方法不能匹配到 若一个类继承了被匹配的接口 则该类也会被拦截

    /**target**/
    @Pointcut("target(com.march.aop.service.ProductService)")
    public void matchTarget(){}

    @Before("matchTarget()")
    public void beforeTarget(){
        System.out.println("###target ");
        authService.checkAccess();
    }

3.4 bean

bean匹配的是spring托管的bean实例

    /**Bean**/
    @Pointcut("bean(authService)")
    public void matchBean(){}

    @Before("matchBean()")
    public void beforeBean(){
        System.out.println("###bean");
        authService.checkAccess();
    }

3.5 args

@Pointcut("args(String,..))")
    public void matchArgs(){}

    @Before("matchArgs()")
    public void beforeArgs(){
        System.out.println("###Args");
        authService.checkAccess();
    }

3.6 annotation

@annotation为方法级别,@within和@target匹配的为类级别,@args为参数级别的注解,以下以@annotation为例:

    /**切入点为带有AdminOnly注解的方法  当程序中该注解并没有被应用时 也就是说不存在该切入点时  程序会报错   **/
    @Pointcut("@annotation(AdminOnly)")
    public void adminOnly(){
    }

    /**在adminOnly方法执行前  做checkAccess的校验**/
    @Before("adminOnly()")
    public void check(){
        authService.checkAccess();
    }

3.7 execution

execution中必要的部分有两个返回值和方法命名(参数) 例子如下:

    /**拦截public 返回值为任意   位于Service包下  类名为Service结尾  其中的任意方法  任意参数  **/
//    @Pointcut("execution(public * com.march.aop.service.ProductService.*(Long) throws java.lang.IllegalAccessError)")
    @Pointcut("execution(public * com.march.aop.service.ProductService.*(Long))")
    public void marchConditicon(){}

    @Before("marchConditicon()")
    public void before(){
        authService.checkAccess();
    }

四 advice

4.1 五中advice

注解意义
@Before在切面方法执行前织入
@After(finally)在切面方法执行后织入
@AfterReturning在切面方法成功执行后织入
@AfterThrowing在切面方法异常后织入
@Around环绕织入

4.2 AfterReturning

@Before和@After同上面的方法区别不大 ,这里说下带有返回值的如何捕获。
ProductService:

/**该方法带有一个String类型的返回值**/
public String delete(Long id){
        System.out.println("delete product");
        return "delete " + id + "  success";
    }

AfterReturningConfig:

 /**this切入PorductService中的方法**/
    @Pointcut("this(com.march.aop.service.ProductService)")
    public void matchThis(){}
/**在该方法正确执行后  获取其返回值并打印**/
    @AfterReturning(value = "matchThis()",returning = "result")
    public void beforeThis(Object result){
        System.out.println("###this result:  "+ result);
//        authService.checkAccess();
    }

执行结果:
这里写图片描述

这里可以看到打印的返回值为 delete 1 success

五 总结

PointcutExpress和Advice可以帮我们准确定位到切面,并能正确的将代码织入,可以使用@AfterThrowing来对抛出的异常进行处理、记录,@Around是一个很全面的注解,它包含了@before和@After。就像Aop的意义一样,善用这些可以让我们在一些特定的情况更加简洁清晰的实现需求。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值