博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
spring-AOP
阅读量:4709 次
发布时间:2019-06-10

本文共 4317 字,大约阅读时间需要 14 分钟。

Spring提供了一个AOP框架,让我把切面插入到方法执行的周围。

1、概念

 定义通用功能,通过申明定义这些功能要以何种方式在何处应用,而不需要修改受影响的类。这些通用功能可以模块化为特殊的类,即切面。

  • 连接点:连接点是一个应用执行过程中能够插入一个切面的点(Spring只支持方法级别的连接点)
  • 切点:定义匹配通知织入的一个或多个连接点(在哪做)
  • 通知:切面的工作(做什么)
  • 切面:由切点和通知的结合
  • 织入:把切面应用到目标对象并创建新的代理对象的过程

 通知分类

  • 前置通知:在目标方法调用之前执行
  • 后置通知:在目标方法执行之后执行,不管是正常执行还是抛了异常
  • 返回通知:在目标方法执行成功后执行,不管方法是否有返回值
  • 异常通知:在目标方法抛出异常后调用
  • 环绕通知:通知方法将目标方法封装起来,可以达到前几种通知的效果

2、Spring切面编程分为:基于注解和基于XML配置形式

  • 基于注解形式

首先开启Aspect代理功能

定义切面,并将该bean交给spring管理

package com.cn.pojo;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.*;import org.springframework.stereotype.Component;@Component@Aspectpublic class Audience {    @Pointcut("execution(* com.cn.pojo.Performance.*(..))")    public void  performance(){}    @Before("performance()")    public void takeSeats(){        System.out.println( "Before:take seats!");    }    @After("performance()")    public void goHome(){        System.out.println("After:go home!");    }    @AfterReturning(value = "performance()", returning = "result")    public void applause(JoinPoint joinPoint,Object result){        System.out.println("AfterReturning:clap clap clap!");        System.out.println("AfterReturning:"+joinPoint.getArgs()[0]);        System.out.println("AfterReturning:applause-当前在场人数:"+result);    }    @AfterThrowing(value = "performance()", throwing = "ex")    public void demandRefund(JoinPoint joinPoint, Exception ex){        System.out.println("AfterThrowing:demanding a refund!");        System.out.println("AfterThrowing:"+joinPoint.getArgs()[0]);        System.out.println("AfterThrowing:异常信息为 "+ex.getMessage());    }    @Around("performance()")    public Object all(ProceedingJoinPoint proceedingJoinPoint){        try{            System.out.println("Around:执行perform方法-前置通知");            Object obj=proceedingJoinPoint.proceed(new Object[]{189});            System.out.println("Around:执行perform方法-返回通知");            return obj;        }catch (Throwable throwable) {            System.out.println("Around:执行perform方法-异常通知");            return -1;        }finally {            System.out.println("Around:执行perform方法---后置通知");        }    }}

 除了execution外,还有以下指示器用于定义切点:

方法入参切点函数
args()
类名
通过判别目标类方法运行时入参对象的类型定义指定连接点。如args(com.baobaotao.Waiter)表示所有有且仅有一个按类型匹配于Waiter的入参的方法。
@args()
类型注
解类名
通过判别目标方法的运行时入参对象的类是否标注特定注解来指定连接点。如@args(com.baobaotao.Monitorable)表示任何这样的一个目标方法:它有一个入参且入参对象的类标注@Monitorable注解。
目标类切点函数
within()
类名匹配串
表示特定域下的所有连接点。如within(com.baobaotao.service.*)表示com.baobaotao.service包中的所有连接点,也即包中所有类的所有方法,而within(com.baobaotao.service.*Service)表示在com.baobaotao.service包中,所有以Service结尾的类的所有连接点。
target()
类名
假如目标类按类型匹配于指定类,则目标类的所有连接点匹配这个切点。如通过target(com.baobaotao.Waiter)定义的切点,Waiter、以及Waiter实现类NaiveWaiter中所有连接点都匹配该切点。
@within()
类型注解类名
假如目标类按类型匹配于某个类A,且类A标注了特定注解,则目标类的所有连接点匹配这个切点。
如@within(com.baobaotao.Monitorable)定义的切点,假如Waiter类标注了@Monitorable注解,则Waiter以及Waiter实现类NaiveWaiter类的所有连接点都匹配。
@target()
类型注解类名
目标类标注了特定注解,则目标类所有连接点匹配该切点。如@target(com.baobaotao.Monitorable),假如NaiveWaiter标注了@Monitorable,则NaiveWaiter所有连接点匹配切点。
  • 基于XML方式

定义POJO

package com.cn.pojo;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.ProceedingJoinPoint;public class Audience {    public void takeSeats(){        System.out.println( "Before:take seats!");    }    public void goHome(){        System.out.println("After:go home!");    }    public void applause(JoinPoint joinPoint,Object result){        System.out.println("AfterReturning:clap clap clap!");    }    public void demandRefund(JoinPoint joinPoint, Exception ex){        System.out.println("AfterThrowing:demanding a refund!");    }    public Object all(ProceedingJoinPoint proceedingJoinPoint){        try{            System.out.println("Around:执行perform方法-前置通知");            Object obj=proceedingJoinPoint.proceed(new Object[]{189});            System.out.println("Around:执行perform方法-返回通知");            return obj;        }catch (Throwable throwable) {            System.out.println("Around:执行perform方法-异常通知");            return -1;        }finally {            System.out.println("Around:执行perform方法---后置通知");        }    }    }

将POJO申明为切面,并交spring管理

 

转载于:https://www.cnblogs.com/shixiemayi/p/9557638.html

你可能感兴趣的文章
通过Html5 Canvas画柱状图
查看>>
青蛙跳台阶(Fibonacci数列)
查看>>
洛谷P3834 [模板]可持久化线段树1(主席树) [主席树]
查看>>
Codeforces Round #316 (Div. 2)C. Replacement(模拟)
查看>>
Python入门学习笔记17(sqlalchemyd的使用)
查看>>
.NET CORE TOKEN 权限验证
查看>>
.Net Core 中间件之主机地址过滤(HostFiltering)源码解析
查看>>
Lucene.Net 2.3.1开发介绍 —— 一、接触Lucene.Net
查看>>
java PDF分页打印
查看>>
数链剖分小结
查看>>
应用nslookup命令查看A记录、MX记录、CNAME记录和NS记录
查看>>
APT攻击
查看>>
做衡八的日子(转自VFleaking)
查看>>
day7.条件和循环
查看>>
(转)log4j(二)——如何控制日志信息的输出?
查看>>
JavaScript简介
查看>>
php.ini中safe_mode开启对PHP系统函数的影响
查看>>
gdb
查看>>
字符串与整数、浮点数、无符号整数之间的转换常用函数
查看>>
ubuntu清理旧内核
查看>>