博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring系列教程——13AspectJ讲解
阅读量:3959 次
发布时间:2019-05-24

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

Spring系列教程——13AspectJ讲解

文章目录

一.Aspect简介及简单实例

1.概念

AspectJ是一个基于Java语言的AOP框架

Spring2.0以后新增了对AspectJ切点表达式支持
@AspectJ 是AspectJ1.5新增功能,通过JDK5注解技术,允许直接在Bean类中定义切面

在使用AspectJ框架之前我们需要在前面章节的基础上导入jar包:

链接:https://pan.baidu.com/s/1YdulOzREOplari0y0slVuA

提取码:rfek

2.AspectJ通知类型

aspectj 通知类型,只定义类型名称,以及方法格式

个数:6种,知道5种,掌握1中。

before:前置通知(应用:各种校验)		在方法执行前执行,如果通知抛出异常,阻止方法运行afterReturning:后置通知(应用:常规数据处理)		方法正常返回后执行,如果方法中抛出异常,通知无法执行		必须在方法执行后才执行,所以可以获得方法的返回值。around:环绕通知(应用:十分强大,可以做任何事情)		方法执行前后分别执行,可以阻止方法的执行		必须手动执行目标方法afterThrowing:抛出异常通知(应用:包装异常信息)		方法抛出异常后执行,如果方法没有抛出异常,无法执行after:最终通知(应用:清理现场)		方法执行完毕后执行,无论方法中是否出现异常

3.案例讲解

接下来我们看一个案例:

定义一个切面类MyAspect2

package aspect;public class MyAspect2 {
public void myBefore(){
System.out.println("我的前置通知"); } public void myAfterReturning(){
System.out.println("我的后置通知"); }}

目标类还是前面章节的:

package service;public class UserServiceImpl implements IUserService {
@Override public void addUser() {
System.out.println("添加User"); } @Override public void deleteUser() {
System.out.println("删除User"); } @Override public void updateUser() {
System.out.println("更新User"); }}

配置文件内容为:

测试代码为:

ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");IUserService userService = (IUserService) context.getBean("userService");userService.updateUser();

在这里插入图片描述

小结:这里我们发现使用AspectJ框架比上一章的全自动还要简洁,我们的切面类根本不需要去实现接口,在这里只要有目标类,切面类,配置就OK了

二.基于XML文件配置的讲解

上一小节我们已经做了一些初步的认识了,这里我们再来继续深入的讲解。上一小节我们为大家演示了前置通知与后置通知。

环绕通知:

//MyAspect2新添下面方法public void myAround(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("环绕通知"); System.out.println("正在使用的方法是:"+pjp.getSignature().getName()); System.out.println("方法的参数为"+pjp.getArgs()); System.out.println("前置代码"); //在使用环绕通知时需要将方法放行 pjp.proceed(pjp.getArgs()); System.out.println("后置代码");}

注意环绕通知需要在切面类的对应方法上加上ProceedingJoinPoint类型参数,因为需要将方法放行才可以生效,当然在我们的上一小节里面的前置与后置的讲解中我们也可以在myBefore与myAfterReturning方法里面添加JoinPoint 类型的参数来获取方法的相关信息(比如方法名字等),还有一点需要注意的就是在后置通知中如果需要获取方法的返回值可以这么写:

//retObj这个参数便是返回值,不过此时还需要在xml文件里面把配置后置通知的地方加上,像这样://
指定ret为返回值public void myAfterReturning(Objiect retObj){
System.out.println("我的后置通知");}

配置文件内容(在上面基础上删除前置与后置,添加环绕通知)

在这里插入图片描述

异常通知:

//myApspect2添加新的方法public void myAfterThrowing(JoinPoint jp,Throwable throwable){
System.out.println("异常通知:"+throwable.getMessage());}

异常通知的配置相关为:

UserServiceImpldeleteUser方法里面加上:

int i=10/0;

还是前面的测试代码,测试结果如下:

在这里插入图片描述
最终通知

//myAspect2里面添加下面方法public void myAfter(){
System.out.println("最终通知");}

此时配置文件内容为:

还是之前的测试代码,测试结果如下:

在这里插入图片描述
我们发现即使在有异常的情况下最终通知仍然会执行。当然没有异常也会执行,不过它都是在最后执行。

三.基于注解配置的讲解

首先我们需要开启注解,初始的xml配置内容应为:

我们来看我们前面实现前置通知的xml文件配置内容:

接下来我们一个一个用注解替换这个前置通知的例子:

1.替换目标业务类(UserServiceImpl)的bean对象和切面类(myAspect2)的bean对象:
在这里插入图片描述
在这里插入图片描述
2.声明切面
在这里插入图片描述
3声明前置通知
在这里插入图片描述
注意这里的execution表达式已经说明了切入点的位置,因此不需要再来声明切入点。
还是之前的测试代码,结果如下:
在这里插入图片描述
接下来我们展示其他的通知:
1.后置通知
在这里插入图片描述
在这里插入图片描述
我们在这里停一下,我们每次写通知注解的时候,都要写execution(* service.UserServiceImpl.*(..))这么长的东西,所以我们可以选择一个公共的方式:
在MyAspect2切面类里面添加下面内容:

@Pointcut("execution(* service.UserServiceImpl.*(..))")public void myPointCut(){
}

上面这个方法名可以随便取,在接下来我们将使用这一方式来简化。

2.环绕通知
在这里插入图片描述
在这里插入图片描述
3.异常通知与最终通知
在这里插入图片描述
这里不再演示结果。

转载地址:http://rtlzi.baihongyu.com/

你可能感兴趣的文章
如何在三个月内学会一门外语?
查看>>
看看你对Linux到底了解多少?
查看>>
网上看到的:ARM入门最好的文章(转)
查看>>
中国最美情诗100句
查看>>
javascript注册window的onload事件问题研究
查看>>
客户端技术分页控件javascript+css,可用于任何服务器端技术
查看>>
学习Swing 的网站[转]
查看>>
Google App engine 的第一个应用 midispot
查看>>
提问的智慧
查看>>
关于dom4j无法解析xmlns问题及生成非UTF-8字符集乱码问题的解决
查看>>
很好的一篇文章 如果让我重做一次研究生 王汎森
查看>>
保护U盘批处理文件
查看>>
hibernate 自动导入sql 文件import.sql 国际化编码的问题的解决方案
查看>>
第七颗头骨 & 忘魂花 凤凰
查看>>
李小龙哲学之言
查看>>
[心情] 如果有一天
查看>>
[Linux] 常用 linux 系统命令及维护备忘
查看>>
[Linux] 关于 Ext4 HowTo
查看>>
[杂记] 新年物语&关于Mysql引擎性能测试
查看>>
[心得] 近期更新&关于Infobright
查看>>