博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
AOP 与 Spring中AOP使用(下)
阅读量:7049 次
发布时间:2019-06-28

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

AOP通知类型

前置通知

在目标方法执行之前进行操作

UserDao.java

public class UserDao {    public void add(){        System.out.println("添加用户");    }}

切面类 MyAspect.java

public class MyAspect {    public void check(){        System.out.println("权限校验");    }}

applicationContext.xml 配置:

AOP测试:

@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration("classpath:applicationContext.xml")public class AopTest {    @Resource(name = "userDao")    private UserDao userDao;    @Test    public void test() {        this.userDao.add();    }}

后置通知

在目标方法执行之后 进行操作

UserDao.java

public class UserDao {    public void add(){        System.out.println("添加用户");    }    public void update(){        System.out.println("更新用户");    }}

切面类 MyAspect.java

public class MyAspect {    public void check(){        System.out.println("权限校验");    }    public void log(){        System.out.println("日志记录");    }}

applicationContext.xml 配置:

AOP测试:

@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration("classpath:applicationContext.xml")public class AopTest {    @Resource(name = "userDao")    private UserDao userDao;    @Test    public void test() {        this.userDao.update();    }}

后置通知获取切入点的返回值

UserDao.java

public class UserDao {    public void add(){        System.out.println("添加用户");    }    public String update(){        System.out.println("更新用户");        return "更新成功!";    }}

切面类 MyAspect.java

public class MyAspect {    public void check(){        System.out.println("权限校验");    }    public void log(Object res){        System.out.println("日志记录:" + res);    }}

applicationContext.xml 配置:

AOP测试:

@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration("classpath:applicationContext.xml")public class AopTest {    @Resource(name = "userDao")    private UserDao userDao;    @Test    public void test() {        this.userDao.update();    }}

环绕通知

在目标方法执行之前 和之后进行操作

UserDao.java

public class UserDao {    public void add(){        System.out.println("添加用户");    }    public String update(){        System.out.println("更新用户");        return "更新成功!";    }    public void delete(){        System.out.println("删除用户");    }}

切面类 MyAspect.java

public class MyAspect {    public void check(){        System.out.println("权限校验");    }    public void log(Object res){        System.out.println("日志记录:" + res);    }    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {        System.out.println("开启事务");        Object proceed = joinPoint.proceed();        System.out.println("提交事务");        return proceed;    }}

applicationContext.xml 配置:

AOP测试:

@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration("classpath:applicationContext.xml")public class AopTest {    @Resource(name = "userDao")    private UserDao userDao;    @Test    public void test() {        this.userDao.delete();    }}

异常抛出通知

在程序出现异常时进行操作

UserDao.java

public class UserDao {    public void add(){        System.out.println("添加用户");    }    public String update(){        System.out.println("更新用户");        return "更新成功!";    }    public void delete(){        System.out.println("删除用户");    }    public void find(){        System.out.println("查找用户");        int i = 1 / 0;    }}

切面类 MyAspect.java

public class MyAspect {    public void check(){        System.out.println("权限校验");    }    public void log(Object res){        System.out.println("日志记录:" + res);    }    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {        System.out.println("开启事务");        Object proceed = joinPoint.proceed();        System.out.println("提交事务");        return proceed;    }    public void exceptionMethod(){        System.out.println("有异常");    }}

applicationContext.xml 配置:

AOP测试:

@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration("classpath:applicationContext.xml")public class AopTest {    @Resource(name = "userDao")    private UserDao userDao;    @Test    public void test() {        this.userDao.find();    }}

异常抛出通知获取异常信息

UserDao.java

public class UserDao {    public void add(){        System.out.println("添加用户");    }    public String update(){        System.out.println("更新用户");        return "更新成功!";    }    public void delete(){        System.out.println("删除用户");    }    public void find(){        System.out.println("查找用户");        int i = 1 / 0;    }}

切面类 MyAspect.java

public class MyAspect {    public void check(){        System.out.println("权限校验");    }    public void log(Object res){        System.out.println("日志记录:" + res);    }    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {        System.out.println("开启事务");        Object proceed = joinPoint.proceed();        System.out.println("提交事务");        return proceed;    }    public void exceptionMethod(Throwable ex){        System.out.println("有异常:" + ex.getMessage());    }}

applicationContext.xml 配置:

AOP测试:

@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration("classpath:applicationContext.xml")public class AopTest {    @Resource(name = "userDao")    private UserDao userDao;    @Test    public void test() {        this.userDao.find();    }}

最终通知

无论代码是否有异常,都会执行

UserDao.java

public class UserDao {    public void add(){        System.out.println("添加用户");    }    public String update(){        System.out.println("更新用户");        return "更新成功!";    }    public void delete(){        System.out.println("删除用户");    }    public void find(){        System.out.println("查找用户");        int i = 1 / 0;    }}

切面类 MyAspect.java

public class MyAspect {    public void check(){        System.out.println("权限校验");    }    public void log(Object res){        System.out.println("日志记录:" + res);    }    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {        System.out.println("开启事务");        Object proceed = joinPoint.proceed();        System.out.println("提交事务");        return proceed;    }    public void exceptionMethod(Throwable ex){        System.out.println("有异常:" + ex.getMessage());    }    public void after(){        System.out.println("最终通知");    }}

applicationContext.xml 配置:

AOP测试:

@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration("classpath:applicationContext.xml")public class AopTest {    @Resource(name = "userDao")    private UserDao userDao;    @Test    public void test() {        this.userDao.find();    }}

AOP切入点表达式

  • 基于execution函数完成

execution语法:

【访问修饰符】 方法返回值 包名.类名.方法名(参数)
public com.myxq.demo2.GoodsDaoImpl.save(..)     // 参数为任意参数* com.myxq.demo2.GoodsDaoImpl.save(..)       // * 为任意类型* com.myxq.demo2.GoodsDaoImpl+.save(..)      // + 当前类和子类* com.myxq..*.*(..)                   // com.myxq包以及子包下面所有类的所有方法

AOP注解方式ApsectJ开发

GoodsDao 接口:

public interface GoodsDao {    public void save();    public String update();    public void delete();    public void find();}

GoodsDao 实现类 GoodsDaoImpl:

public class GoodsDaoImpl implements GoodsDao {    @Override    public void save() {        System.out.println("保存操作");    }    @Override    public String update() {        System.out.println("更新操作");        return "更新完成";    }    @Override    public void delete() {        System.out.println("删除操作");    }    @Override    public void find() {        System.out.println("查询操作");        int i = 1 / 0;    }}

1. 引入Jar包

1472533-20190512153230259-549434903.png

2. 引入配置文件

applicationContext.xml

3. 编写切面类配置

public class GoodsDaoAspect {    public void log(){        System.out.println("前置增强");    }}

将切面类交给 spring 管理,applicationContext.xml 配置:

4. 使用注解的AOP对象目标类进行增强

在配置文件 applicationContext.xml 中开启以注解形式进行AOP开发

在切面类上添加注解

@Aspectpublic class GoodsDaoAspect {    @Before(value = "execution(* com.xzh.spring.demo5.GoodsDaoImpl.save(..))")    public void before(){        System.out.println("前置增强");    }}

测试

@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration("classpath:applicationContext.xml")public class GoodsTest {    @Resource(name = "goodsDao")    private GoodsDao goodsDao;    @Test    public void test(){        this.goodsDao.save();    }}

5. 注解AOP通知类型

@Before 前置通知

切面类:

@Aspectpublic class GoodsDaoAspect {    @Before(value = "execution(* com.xzh.spring.demo5.GoodsDaoImpl.save(..))")    public void before(){        System.out.println("前置增强");    }}

@AfterReturning 后置通知

(1)没有返回值

切面类:

@Aspectpublic class GoodsDaoAspect {    @AfterReturning(value = "execution(* com.xzh.spring.demo5.GoodsDaoImpl.update(..))")    public void afterReturning(){        System.out.println("后置通知");    }}

(2)有返回值

切面类:

@Aspectpublic class GoodsDaoAspect {    @AfterReturning(value = "execution(* com.xzh.spring.demo5.GoodsDaoImpl.update(..))", returning = "res")    public void afterReturning(Object res){        System.out.println("后置通知" + res);    }}

1472533-20190512153240090-929795259.png

@Around 环绕通知

切面类:

@Aspectpublic class GoodsDaoAspect {    @Around(value = "execution(* com.xzh.spring.demo5.GoodsDaoImpl.delete(..))")    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {        System.out.println("开启事务");        Object proceed = joinPoint.proceed();        System.out.println("提交事务");        return proceed;    }}

@AfterThrowing 异常抛出通知

(1)没有获取异常信息

切面类:

@Aspectpublic class GoodsDaoAspect {    @AfterThrowing(value = "execution(* com.xzh.spring.demo5.GoodsDaoImpl.find(..))")    public void afterThrowing(){        System.out.println("异常通知");    }}

(2)获取异常信息

切面类:

@Aspectpublic class GoodsDaoAspect {    @AfterThrowing(value = "execution(* com.xzh.spring.demo5.GoodsDaoImpl.find(..))", throwing = "ex")    public void afterThrowing(Throwable ex){        System.out.println("异常通知" + ex.getMessage());    }}

@After 最终通知

无论代码是否有异常,都会执行

切面类:

@Aspectpublic class GoodsDaoAspect {    @After(value = "execution(* com.xzh.spring.demo5.GoodsDaoImpl.find(..))")    public void after(){        System.out.println("最终通知");    }}

6. 定义多个切入点

一个通知同时定义到多个方法当中

@Aspectpublic class GoodsDaoAspect {    @Before(value = "execution(* com.xzh.spring.demo5.GoodsDaoImpl.save(..)) || execution(* com.xzh.spring.demo5.GoodsDaoImpl.delete(..))")    public void before (){        System.out.println("前置通知");    }}

7. AOP的注解切入点的配置

可以在切面当中定义好切入点,在通知当中直接使用定义好的切入点表达式

@Aspectpublic class GoodsDaoAspect {    @Before(value = "GoodsDaoAspect.pointSave() || GoodsDaoAspect.pointDelete()")    public void before (){        System.out.println("前置通知");    }    @Pointcut(value = "execution(* com.xzh.spring.demo5.GoodsDaoImpl.save(..))")    private void pointSave(){}  // 写一个空方法,相等于给切点起别名    @Pointcut(value = "execution(* com.xzh.spring.demo5.GoodsDaoImpl.delete(..))")    private void pointDelete(){}}

8. 当使用接口时与不使用接口内部代理区别

(1)使用接口 JDK动态代理

1472533-20190512155826782-396600856.png

(2)不使用接口 CGLIB代理

1472533-20190512155830614-1409246284.png

转载于:https://www.cnblogs.com/xzh0717/p/10850929.html

你可能感兴趣的文章
ORA-12571: TNS:packet writer failure
查看>>
Android:WebView(慕课网)
查看>>
JS中的数学计算<之简单实例讲解>
查看>>
Android开发之ExpandableListView扩展(BaseExpandableListAdapter的使用)(完整版)
查看>>
深入理解JS的delete
查看>>
BZOJ2085 : [Poi2010]Hamsters
查看>>
proc文件系统、sysfs文件系统、kobject操作
查看>>
发送验证码
查看>>
多线程开发之三 GCD
查看>>
在scrollView中使用pageControl
查看>>
MongoDB Linux环境安装及配置[转]
查看>>
错误 1 未知的服务器标记“asp:ScriptManager”。
查看>>
Spark里边:Worker源代码分析和架构
查看>>
WebForm和MVC中都可以使用的路由
查看>>
解决 - java.lang.OutOfMemoryError: unable to create new native thread
查看>>
(算法)二分查找的搜索区间
查看>>
linux Cron 执行Django 任务计划
查看>>
hdu 5465 Clarke and puzzle(前缀和,异或,nim博弈)
查看>>
Android采用Volley具体的例子展示完整的异步加载数据(一)
查看>>
ZetCode PyQt4 tutorial widgets II
查看>>