目录
4.3.2.返回通知:正常执行完切入的方法,没有异常,执行的通知
4.3.5.环绕通知:可以设置上面四种通知,同时与上面四个使用时,环绕优先级高于上面四种
1、什么是AOP?
面向切面编程。面对面到面的切入
2、为什么使用AOP?
1、降低模块之间的耦合度,提高业务代码的聚合度
2、提高代码的复用性
3、提高系统的扩展性
4、可以在不影响原有功能上添加新的功能
3、底层实现和环境变量配置
底层实现:JDK动态代理+CGLIB动态代理
环境变量:
1、pom.xml添加依赖
<dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.8.9</version> </dependency>
2、xml配置文件中添加规范
xmlns:aop="http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd
<!-- 开启AOP自动代理(注释代理)--> <aop:aspectj-autoproxy/>
4、AOP基本概念
1、Joinpoint(连接点)
2、Pointcut(切入点)
3、Advice(通知)
4、Aspect(切面)
5、Target(目标对象)
6、Weave(织入)
7、Introducting(引入)
4.1、Joinpoint(连接点)
每一个被拦截的方法叫做连接点
4.2、Pointcut(切入点)
对连接点进行拦截的定义,规定把哪些方法作为连接点
一、实现方法(注释)
@Pointcut("execution(* com.wode.service..UserDao.*(..))") public void cut(){}
execution组成:1、修饰符(*是通配符,代表任意修饰符)
2、方法名:(包结构,例com.xxxx.service)+
(有包结构的情况下,后接一个“.”代表包下不包括子包,两个".."代表包下以及子包)+
(有包结构的情况下,表示类名,可以使用通配符*表示任意,之后接“.”)+
方法名(..),方法名可以用通配符*表示任意,例*(..)
注:括号内的结构可以省略,即可以不限定包结构,没有包结构时不能写类名
二、配置文件法
ref:实现切面的类名——切面类
id:切入点名
expression:规定哪些方法是连接点,编写规则同上
<aop:config> <aop:aspect ref="Cut"> <aop:pointcut id="cut" expression="execution(* com.wode.service..*.*(..))"/> </aop:aspect> </aop:config>
4.3、Advice(通知)
拦截到每一个连接点后做的操作
4.3.1.前置通知:在方法执行前通知
注释法 @Before(value = "cut()") public void before(){ System.out.println("前置通知"); }
配置文件法,写在切面下,method为指向的方法,pointcut-ref为切入点 <aop:before method="before" pointcut-ref="cut"/>
4.3.2.返回通知:正常执行完切入的方法,没有异常,执行的通知
注释法
@AfterReturning(value = "cut()") public void afterReturn(){ System.out.println("返回通知"); }
配置文件法
<aop:after-returning method="afterReturn" pointcut-ref="cut"/>
4.3.3.异常通知:当切入的方法执行异常,执行的同通知
注释法
@AfterThrowing(value = "cut()",throwing = "e") public void throwReturn(Exception e){ System.out.println("异常通知,并且抛出异常信息"+e.getMessage()); }
配置文件法,throwing为接收的异常信息
<aop:after-throwing method="throwReturn" pointcut-ref="cut" throwing="e"/>
4.3.4.最终抛出通知:无论成功还是失败,都会执行的通知
注释法
@After(value = "cut()") public void after(){ System.out.println("最终通知"); }
配置文件法
<aop:after method="after" pointcut-ref="cut"/>
4.3.5.环绕通知:可以设置上面四种通知,同时与上面四个使用时,环绕优先级高于上面四种
注释法
@Around(value = "cut()") public Object around(ProceedingJoinPoint pjp){ System.out.println("环绕中的前置"); Object object=null; try { //需要显式调用对应的方法,否则无法访问指定方法 object=pjp.proceed(); System.out.println("环绕中的正常通知"); } catch (Throwable throwable) { throwable.printStackTrace(); System.out.println("环绕中的异常通知"+throwable.getMessage()); } System.out.println("环绕中的最终通知"); return object; }
配置文件法
<aop:around method="around" pointcut-ref="cut"/>
4.4、Aspect(切面)
切入点和通知的结合,决定切面的定义,切入点定义要拦截的方法,通知则定义拦截后需要做什么,切面则是横切关注点的抽象
注释方法
@Aspect //表示当前是切面类 public class Cut { //切入点 //通知 }
配置文件方法
<aop:config> <aop:aspect ref="Cut"> <切入点> <通知> </aop:aspect> </aop:config>
4.5、Target(目标对象)
被代理的目标对象(AOP底层是动态代理实现的)
4.6、Weave(织入)
将切面应用到目标对象并生成代理对象的过程
4.7、Introducting(引入)
在不修改原有应用程序代码的情况下,在程序运行期为类动态添加方法或者字段的过程