Sring AOP通过PointCut来指定在那些类的那些方法上织入横切逻辑,通过Advice来指定在切点上具体做什么事情。如方法前做什么,方法后做什么,抛出异常做什么。

Spring中有两种方式定义Pointcut:

·XML文件

·注解

XML与注解方式类似,学会了一种,另外一种无难度上手。

Advice接口的接口继承类:

主要可分为5类增强:

·MthodBeforeAdvice:目标方法实施前增强

·AfterReturningAdvice:目标方法实施后增强

·ThrowsAdvice 异常抛出增强

·IntroductionAdvice 引介增强,为目标类添加新的属性和方法。可以构建组合对象来实现多继承

·MethodInterceptor 方法拦截器,环绕增强,在方法的前后实施操作

AfterAdvice,BeforeAdvice当前是作为标记使用,内部无接口方法,为后来扩展使用。

Interceptor接口也不是直接使用,同样作为标记类,可使用其子接口。

前置增强主要在匹配到的切点运行之前执行,在XML配置中使用,相应的接口为MethodBeforeAdvice,其方法为

当一个Bean对象实现了MethodBeforeAdvice,在XML配置文件中指定这个bean为advice,Spring会自动在切点方法执行前执行MethodBeforeAdvice的接口。

在调用相应的切点方法之前,前置增强都会生效。

弄明白了前置增强,后置增强也是同一个道理,不过后置增强是在切点运行后执行。接口为AfterReturningAdvice,方法为

在切点方法运行之后,后置增强会生效。

当切点方法抛出异常时,异常抛出增强才会被执行。其接口为ThrowsAdvice,接口没有指定方法,实现这个接口的对象是通过反射来调用其增强方法的。

根据前面的前置,后置,异常抛出增强,看一个完整的案例:

通过上面这个案例,我们大体知道什么是增强,字面意思:

在原本方法之上增加一些额外的东西,原本的功能增强了,所以叫增强,这是中文翻译过来的增强。

英文名为Advice,建议,在方法周围建议方法做什么事情,然后真的做了...

环绕增强可以理解为前置增强,后置增强,异常抛出增强的结合体,只有一个接口MethodInterceptor,其方法为:

Object intercept(Object var1, Method var2, Object[] var3, MethodProxy var4) throws Throwable;

当多个增强作用与同一个切点的时候,具体哪一个增强会先执行呢?

Spring根据@Order注解或者实现了Ordered接口的增强类来进行判断。

增强的概念一样,在使用方式上稍微有点区别,增强的相关注解有:

@Before

@AfterReturning

@AfterThrowing(

@After //相当于try-catch-finally中的final,一般用于释放资源

@Around

使用上与接口差不多

增强是AOP中核心概念之一,今后会继续探讨。

2019年8月8日更新:

博主近日在项目中需要配置多数据源,并且要实现带事务的动态切换,于是上网查找办法,最后采用的spring多数据源配置实现带事务的动态切换,但是在该过程中遇到了一个问题,就是数据源动态切换到非默认数据源时,一旦目标方法抛出异常会导致数据源切换失败,翻阅了spring的AOP增强后,发现可以解决这个问题,具体的实现参看博主的博文:https://www.cnblogs.com/nietzsche2019/p/11305654.html

下面是在实现ThrowsAdvice接口时遇到问题,记录下来希望能帮到大家:

在实现ThrowsAdvice接口时,发现不会自动重写方法,但是运行时会出现异常,无奈上网查资料发现该接口中没有任何抽象方法,查找了相关资料发现,Spirng内部是用反射来实现方法匹配的,需要实现下列接口中的其中1个:

public void afterThrowing(Exception e);
public void afterThrowing(RemoteException re);
public void afterThrowing(Metho method, Object[] args, Object target, Exception e);
public void afterThrowing(Metho method, Object[] args, Object target, ServletException e);

Spirng设计者可能感觉如果全部声明成抽象方法的话,实现该接口就必须全部重写,代码冗余较高,所以干脆直接做成标识接口了。

最新文章

  1. Oracle函数over(),rank()over()作用及用法--分区(分组)求和& 不连续/连续排名
  2. Microsoft Naive Bayes 算法——三国人物身份划分
  3. android系统架构解析
  4. POJ 1185 炮兵阵地(经典的状态压缩DP)
  5. Docs list
  6. 八位彻底改变App Store的iOS开发者
  7. [Raobin] Ext.net 页面由于CMB的store和对图像同时执行,所以不会触发非空验证 所以会在后台直接调Js去验证
  8. JamCam创业故事:辞掉工作,去开发一个应用
  9. Stanford CoreNLP--Named Entities Recognizer(NER)
  10. IOS-CGAffineTransformMake 矩阵变换 的运算原理
  11. eclipse中如何创建maven项目
  12. C语言基础09
  13. 男性在下一100层【第三层】——高仿手机银行client接口
  14. css中margin重叠和一些相关概念(包含块containing block、块级格式化上下文BFC、不可替换元素 non-replaced element、匿名盒Anonymous boxes )
  15. java 多线程之卖票两种方式
  16. [编织消息框架][netty源码分析]12 ByteBuf 实现类UnpooledDirectByteBuf职责与实现
  17. [CVPR2017] Weakly Supervised Cascaded Convolutional Networks论文笔记
  18. js检查身份证号是否正确
  19. WPF中在MVVM模式下,后台绑定ListCollectionView事件触发问题
  20. 学习 Hadoop3.0 一、Hadoop3.0的安装与配置

热门文章

  1. 通过Callable接口实现多线程
  2. Odoo的菜单项
  3. 关于SAMBA的关键参考资源
  4. 《python解释器源码剖析》第2章--python中的int对象
  5. CentOS7.x卸载与安装MySQL5.7的操作过程以及编码格式的修改
  6. 解决国内安装tensorflow, opencv等安装不成功或下载太慢问题
  7. zencart产品批量表上传后SEO三要素状态以及特价时间修改
  8. servlet 如何处理多请求访问以及线程讲解
  9. vue 图片滑动登录
  10. Python之exec()/compile()方法使用