转载自 https://www.cnblogs.com/ltfxy/p/9882697.html
Spring中通知类型:
- 前置通知:目标方法执行之前进行操作,可以获得切入点信息
- 后置通知: 目标方法执行之后进行操作,可以获得方法的返回值
- 环绕通知:在目标方法执行之前和之后进行操作,可以终止目标方法的执行
- 异常抛出通知:在程序出现异常的时候进行的操作,可以返回异常信息
- 最终通知:无论代码是否有异常,总是执行,相当于finally
- 引介通知(了解即可):
切面类:
配置:
测试结果:
环绕通知:目标方法执行之前和之后进行操作(事务管理),可以阻止目标方法的执行
异常抛出通知:程序出现异常的时候进行的操作
最终通知:无论代码是否有异常,总是会执行
引介通知:(了解)
applictionContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- 配置目标对象(被增强对象) --> <bean id="productDao" class="com.spring4.demo3.ProductDaoImpl"></bean> <!-- 将切面类交给Spring管理 --> <bean id="myAspect" class="com.spring4.demo3.MyAspectXML"> </bean> <!-- 通过Spring配置对目标类完成代理 --> <aop:config> <!-- 配置切入点,表达式配置哪些类的哪些方法需要进行增强,*代表任意返回值,...代表任意参数 --> <aop:pointcut expression="execution(* com.spring4.demo3.ProductDaoImpl.save(..))" id="pointcut1" /> <aop:pointcut expression="execution(* com.spring4.demo3.ProductDaoImpl.delete(..))" id="pointcut2" /> <aop:pointcut expression="execution(* com.spring4.demo3.ProductDaoImpl.update(..))" id="pointcut3" /> <aop:pointcut expression="execution(* com.spring4.demo3.ProductDaoImpl.find(..))" id="pointcut4" /> <!-- 配置切面 --> <aop:aspect ref="myAspect"> <!-- 配置前置增强 --> <aop:before method="checkPri" pointcut-ref="pointcut1" /> <!-- 配置后置增强,设置返回值为result --> <aop:after-returning method="log4j" pointcut-ref="pointcut2" returning="result" /> <!-- 环绕通知 --> <aop:around method="around" pointcut-ref="pointcut3"/> <!-- 异常抛出通知,设置异常信息为ex --> <aop:after-throwing method="afterThtowing" pointcut-ref="pointcut4" throwing="ex"/> <!-- 最终通知 --> <aop:after method="after" pointcut-ref="pointcut4"/> </aop:aspect> </aop:config> </beans>
Java
1 package com.itheima.spring.demo3;
2
3 public class ProductDaoImpl implements ProductDao { 4 5 @Override 6 public void save() { 7 System.out.println("保存商品"); 8 } 9 @Override 10 public void update() { 11 System.out.println("修改商品"); 12 } 13 @Override 14 public void find() { 15 System.out.println("查找商品"); 16 // int i = 1/0; 17 } 18 @Override 19 public String delete() { 20 System.out.println("删除商品"); 21 return "赵洪"; 22 23 } 24 25 } 26 27 28 package com.itheima.spring.demo3; 29 30 import org.aspectj.lang.ProceedingJoinPoint; 31 32 /** 33 * 切面:切入点和通知的组合 34 * @author 李腾 35 */ 36 public class MyAspectXml { 37 /** 38 * 前置通知 39 * @param joinpoint 40 */ 41 public void checkPri(){ 42 System.out.println("权限校验======="); 43 } 44 /** 45 * 后置通知 46 */ 47 public void writeLog(Object result){ 48 System.out.println("日志记录======"+result); 49 } 50 /** 51 * 环绕通知 52 * @throws Throwable 53 */ 54 public Object aruond(ProceedingJoinPoint joinPoint) throws Throwable{ 55 System.out.println("环绕通知======="); 56 Object obj = joinPoint.proceed(); 57 System.out.println("环绕通知======="); 58 return obj; 59 } 60 /** 61 * 异常抛出通知 62 */ 63 public void afterThrowing(Throwable ex){ 64 System.out.println("异常抛出通知"+ex.getMessage()); 65 } 66 /** 67 * 最终通知: 相当于finally代码块 68 */ 69 public void after(){ 70 System.out.println("最终通知====="); 71 } 72 } 73 74 75 package com.itheima.spring.demo3; 76 import javax.annotation.Resource; 77 78 import org.junit.Test; 79 import org.junit.runner.RunWith; 80 import org.springframework.test.context.ContextConfiguration; 81 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 82 /** 83 *测试类 84 */ 85 @RunWith(SpringJUnit4ClassRunner.class) 86 @ContextConfiguration("classpath:applicationContext.xml") 87 public class SpringDemo3 { 88 89 @Resource(name="productDao") 90 private ProductDao productDao; 91 @Test 92 public void demo1(){ 93 productDao.save(); 94 productDao.update(); 95 productDao.delete(); 96 productDao.find(); 97 98 } 99 }
切入点表达式语法:基于execution函数完成的