说到AOP肯定会想到切面、通知、切点等等。那什么是通知呢?之前我一直以为我们所说的通知就是我们写在切面中的方法,但是随着AOP认识的加深,现在发现所谓的通知不仅仅是我们写在切面中的方法,通知方法只是通知的一部分。也就是说我们在切面中定义的通知方法会被包装成一个真正的通知对象。通知有五种类型、他们的继承层次是什么样子?看下图:

这五个通知都继承AbstractAspectJAdvice抽象类,所以这个抽象类非常重要。Advice是一个空接口,所以就不介绍了,不过它有非常多的子接口和实现类。

一、AbstractAspectJAdvice

一)、AbstractAspectJAdvice的属性

AbstractAspectJAdvice的五个子类都没有属性,所以它们的属性都在这个抽象类中。一个对象是什么东西,主要看它的属性。所以一个通知到底是什么样子的,那就要看看这个通知的有什么属性。如下图,一个通知有许多的属性,为了能够想清楚一个通知大概是什么样子的,那就先看看它主要有哪些中要的属性。

一个通知有以下几个中要的属性:

①、切面的名称(bean的名称):也就是通知方法所在的切面
②、切面所属类型的类对象:切面对应的Class对象。
③、通知方法的名称:方法名,不包括参数。
④、通知方法对应的Method的对象:
⑤、通知方法的参数:这些参数方法一个数组中。
⑥、切点

我们在定义一个切面的时候通常会在里面定义好几个通知,如:前置通知、后置通知等等。但是我们在包装的时候,会将切面中的前置通知方法、切面、切点包装成一个AspectJBeforeMethodAdvice 对象。所以现在要是谈到一个通知,应该要想到一个通知具体是什么样子,它应该包含它所处的切面信息,切点信息,还有通知方法等,我觉得只要你能想到上面的六个主要属性,说明对通知算是了解了。

下面我把我debug时候的记录一个通知对象的几个属性和属性值,如下:蓝色为属性名,冒号后面是属性值。

declaringClass:class com.zcd.MyAspect----->切面所属类型的类对象。Class对象

aspectName:myAspect---->切面的名字

aspectJAdviceMethod: public void com.zcd.MyAspect.after()------>通知方法,Method对象

methodName:after---->方法名字

parameterTypes: []---->通知方法的参数。

declarationOrder: 5

pointcut:AspectJExpressionPointcut: () execution(* com.zcd.*.*(..))---->切点。AspectJExpressionPointcut对象

知道了一个通知对象由什么属性只是了解了这个对象长什么样子。但这个对象能干什么,有什么行为,这就需要看看它由什么主要的方法了。

二)、AbstractAspectJAdvice的主要方法

这个类的方法好像有点多,不过最最重要的方法也只有几个。我们在切面中定义一个通知方法就是为了让通知方法能够在适当的时机执行,而一个通知对象中又包含有通知方法,那么很有可能这个通知对象会负责这个通知方法的调用,也就是说在程序执行的过程会通过这个通知对象来调用通知方法。所以现在来看看这个通知对象是怎么调用通知方法的,这一任务由哪几个方法来完成。

一下三个方法就是为了完成通知方法的调用的:

①、根据这个方法的名字就知道它的任务就是调用通知方法了。它会在内部调用第三个方法。

    /**
* Invoke the advice method.
* @param jpMatch the JoinPointMatch that matched this execution join point
* @param returnValue the return value from the method execution (may be null)
* @param ex the exception thrown by the method execution (may be null)
* @return the invocation result
* @throws Throwable in case of invocation failure
*/
protected Object invokeAdviceMethod(JoinPointMatch jpMatch, Object returnValue, Throwable ex) throws Throwable {
return invokeAdviceMethodWithGivenArgs(argBinding(getJoinPoint(), jpMatch, returnValue, ex));
}

②、这个第一个方法的重载方法。

    // As above, but in this case we are given the join point.
protected Object invokeAdviceMethod(JoinPoint jp, JoinPointMatch jpMatch, Object returnValue, Throwable t)
throws Throwable { return invokeAdviceMethodWithGivenArgs(argBinding(jp, jpMatch, returnValue, t));
}

③、这个三个方法中最重要的方法。

    protected Object invokeAdviceMethodWithGivenArgs(Object[] args) throws Throwable {
Object[] actualArgs = args;//这是通知方法的参数.
if (this.aspectJAdviceMethod.getParameterTypes().length == 0) {
actualArgs = null;//如果通知方法中参数为空的话,就将actualArgs设为null.
}
try {
ReflectionUtils.makeAccessible(this.aspectJAdviceMethod);
// TODO AopUtils.invokeJoinpointUsingReflection 将切面和通知方法的参数传进去
return this.aspectJAdviceMethod.invoke(this.aspectInstanceFactory.getAspectInstance(), actualArgs);//通过这一句代码调用通知方法。
}
catch (IllegalArgumentException ex) {
throw new AopInvocationException("Mismatch on arguments to advice method [" +
this.aspectJAdviceMethod + "]; pointcut expression [" +
this.pointcut.getPointcutExpression() + "]", ex);
}
catch (InvocationTargetException ex) {
throw ex.getTargetException();
}
}

AOP-通知-笔记的更多相关文章

  1. Spring AOP学习笔记

      Spring提供了一站式解决方案:          1) Spring Core  spring的核心功能: IOC容器, 解决对象创建及依赖关系          2) Spring Web ...

  2. Spring学习(十五)----- Spring AOP通知实例 – Advice

    Spring AOP(面向方面编程)框架,用于在模块化方面的横切关注点.简单得说,它只是一个拦截器拦截一些过程,例如,当一个方法执行,Spring AOP 可以劫持一个执行的方法,在方法执行之前或之后 ...

  3. Spring AOP通知实例 – Advice

    Spring AOP(面向方面编程)框架,用于在模块化方面的横切关注点.简单得说,它只是一个拦截器拦截一些过程,例如,当一个方法执行,Spring AOP 可以劫持一个执行的方法,在方法执行之前或之后 ...

  4. AOP通知无法切入指定方法

    AOP通知,切入指定方法时拦截不到,可能是拦截的方法本身是被本类的其他方法调用的,根据AOP反射原理是无法拦截本类中方法调用的方法的.如: class AImpl implements AIf { s ...

  5. Spring基础——AOP通知

    spring(AOP通知) 切面 切面是封装通用业务逻辑的组件,可以作用到其他组件上.是spring组件中的某个方法.无返回类型.参数类型与通知类型有关.一个切面 开启数据库 关闭数据库 开启事务 检 ...

  6. AOP通知类型

    AOP通知类型 前置通知 在目标方法执行之前进行操作 后置通知 在目标方法执行之后 进行操作 环绕通知 在目标方法执行之前 和之后进行操作 public Object arount() 异常抛出通知 ...

  7. Spring入门IOC和AOP学习笔记

    Spring入门IOC和AOP学习笔记 概述 Spring框架的核心有两个: Spring容器作为超级大工厂,负责管理.创建所有的Java对象,这些Java对象被称为Bean. Spring容器管理容 ...

  8. Aop学习笔记

    在学习编程这段时间我想大家都是习惯了面向过程或者面向对象的思想来编程,较少或者没有接触过面向方面编程的思想. 那么什么是面向方面(Aspect)——其实就是与核心业务处理逻辑无关的切面,例如记录日志. ...

  9. Spring系列26:Spring AOP 通知与顺序详解

    本文内容 如何声明通知 如何传递参数到通知方法中 多种通知多个切面的通知顺序 多个切面通知的顺序源码分析与图解 声明通知 Spring中有5种通知,通过对应的注解来声明: @BeforeBefore ...

  10. .Net中的AOP读书笔记系列之AOP介绍

    返回<.Net中的AOP>系列学习总目录 本篇目录 AOP是什么? Hello,World! 小结 本系列的源码本人已托管于Coding上:点击查看,想要注册Coding的可以点击该连接注 ...

随机推荐

  1. 边框圆角Css

    .box{ background:grey; //灰色背景 height:50px; //高500像素 width:200px; //宽200像素 border-top-left-radius:15p ...

  2. centos7 离线安装Ambari

    准备工作: 新下载的centos7 安装 createrepo,用于制作源 yum install createrepo 安装java (推荐 java 1.7以上版本,如果有,则跳过此步骤) yum ...

  3. [日常] Go语言圣经-WEB服务与习题

    Go语言圣经-web服务 1.Web服务程序,标准库里的方法已经帮我们完成了大量工作 2.main函数将所有发送到/路径下的请求和handler函数关联起来,/开头的请求其实就是所有发送到当前站点上的 ...

  4. HTTPS 常见部署问题及解决方案

    在最近几年里,我写了很多有关 HTTPS 和 HTTP/2 的文章,涵盖了证书申请.Nginx 编译及配置.性能优化等方方面面.在这些文章的评论中,不少读者提出了各种各样的问题,我的邮箱也经常收到类似 ...

  5. 无效的列类型:getTimestamp not implemented for class oracle.jdbc.driver.T4CNumberAccessor

    错误信息: 无效的列类型:getTimestamp not implemented for class oracle.jdbc.driver.T4CNumberAccessor 错误原因:经过排查发现 ...

  6. 2017年5月22日 HTML基础知识(一)

    一.Html 结构 1.1.HTML基本文档格式—<html> 标记 —<html>文档的头部好和主体内容 </html>  根标记 —<head> 文 ...

  7. 前端模块化工具--webpack学习心得

    话说前头 webpack前段时间有听说一下,现在已经到了3.x的版本,自己没去接触.因为之前使用gulp来作为自己的项目构建工具.现在感觉gulp使用的趋势在减少.现在这段时间去接触了webpack, ...

  8. dbms_random 包的使用

    dbms_random是一个可以生成随机数值或者字符串的程序包. 这个包有 initialize(),seed(),terminate(),value(),normal(),random(),stri ...

  9. form插件ajaxForm和ajaxSubmit方法传递对象参数说明

    form插件的ajaxForm和ajaxSubmit方法的Options对象还可以用来将值传递给jQuery的$.ajax方法.如果你熟悉$.ajax所支持的options,你可以利用它们来将Opti ...

  10. Java各种数据库连接大全

    1.Oracle8/8i/9i数据库(thin模式) Class.forName("oracle.jdbc.driver.OracleDriver").newInstance(); ...