一、AOP的定义
AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
二、AOP的优点
对业务逻辑各个部分进行隔离,从而降低各部分之间的耦合度,提高开发效率。
在不修改源代码的情况下,对程序进行增强
三、AOP的实现
aop的底层实现:JDK动态代理和Cglib动态代理。
JDK代理:只能对实现接口的类产生动态代理
Cglib代理:对没有实现接口的类产生动态代理
四、AOP的常用术语
Joinpoint:连接点,可以被拦截到的点
Pointcut:切入点:真正被拦截到的点
Advice:增强的方法,通知
Target:目标对象(被增强的目标)
Weaving:织入,代表的是一种过程,将通知应用到目标的过程
Proxy:代理对象。(Aspectj)生成的代理对象
Aspect:多个切面和切入点的组合
五、通知类型
(1)前置通知:在目标方法执行之前进行操作
(2)后置通知:在目标方法执行之后进行操作
(3)环绕通知:在目标方法执行之前之后进行操作
(4)异常抛出通知:在程序出现异常的时候进行操作
(5)最终通知:无论如何最终都会执行
六、配置与实现AOP
(1)引入约束
<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">............................
</beans>
(2)将需要增强的类交给·Spring管理
<bean id="productDao" class="demo.ProductDaoImpl"/>
(3)配置切面类,将切面类交给Spring管理
<bean id="myAspect" class="demo.MyAspect"/>
(4)配置切入点
<aop:config>
<!-- 配置切入点
expression配置哪些类哪些的方法要进行增强
execution(* demo.ProductDaoImpl.save(..))
* : 表示返回任何参数类型的数据
(..) : 表示可以接收任意参数
-->
<aop:pointcut expression="execution(* demo.ProductDaoImpl.save(..))" id="pointcut1"/>
<aop:pointcut expression="execution(* demo.ProductDaoImpl.delete(..))" id="pointcut2"/>
<aop:pointcut expression="execution(* demo.ProductDaoImpl.update(..))" id="pointcut3"/>
<aop:pointcut expression="execution(* demo.ProductDaoImpl.find(..))" id="pointcut4"/>
<aop:pointcut expression="execution(* demo.ProductDaoImpl.find(..))" id="pointcut4"/>.........................
</aop:config>
expressio= execution(* demo.ProductDaoImpl.save(..))
* : 表示返回任何参数类型的数据
(..): 表示可以接收任意参数
(5)配置切面,在<aop:config>里配置·
<!-- 配置切面 -->
<!--
aop:aspect的配置
ref : 引入切面
-->
<aop:aspect ref="myAspect" >....................
</aop:aspect>
(6)配置通知
1、前置通知
<!--
aop:~的配置
method : 切面中的方法
point-ref : 引入切点
--><!-- 前置通知 -->
<aop:before method="checkPri" pointcut-ref="pointcut1"/>
补充:获取切入点信息
public void checkPri(JoinPoint joinPoint){
System.out.println("权限校验========"+joinPoint);
}
2、后置通知
<!-- 后置通知
使用 aop:after-returning表示进行后置通知操作
returning : 方法返回值,此返回值的名称必须和切面接收参数名称一样
-->
<aop:after-returning method="writeLog" pointcut-ref="pointcut2" returning="result"/>
我们使用后置通知的时候,如果进行操作之后,需要返回一些值。我们可以通过后置通知,接收返回值。
第一步:在配置文件中,申明returning="result";
第二步:在切面类中写上
public void writeLog(Object result){
System.out.println("日志记录========"+result);
}
注意参数类型为Object类型,参数名称与returning=“**”中的名称一致。
3、环绕通知
<!-- 环绕通知 -->
<aop:around method="around" pointcut-ref="pointcut3"/>
相对于·其他通知而言,环绕通知略有不同
/**
* 环绕通知,在方法执行前后进行通知
* 接收ProceedingJoinPoint对象
* joinPoint.proceed()调用执行的方法
* 返回object对象,以防执行的方法有返回值
* @param joinPoint
* @return
* @throws Throwable
*/
public Object around(ProceedingJoinPoint joinPoint) throws Throwable{
System.out.println("环绕执行前======");
Object obj = joinPoint.proceed();
System.out.println("环绕执行后======");
return obj;
}
接收ProceedingJoinPoint对象,
调用proceed(),执行方法,
方法返回值为Object类型
4、异常通知
<!-- 异常通知
throwing 返回异常信息
-->
<aop:after-throwing method="afterThrowing" pointcut-ref="pointcut4" throwing="ex"/>
如果想要异常的返回值信息,在切面类中如下书写
/**
* ex对应着xml配置的Throwing的参数,名称一致,返回异常信息
* @param ex
*/
public void afterThrowing(Throwable ex){
System.out.println("异常抛出通知======"+ex);
}
其中的接收参数名称要与xml配置的Throwing的参数名称,保持一致
5、最终通知,无论如何都会执行的通知·
<!-- 最终通知
相当于finally中的代码块,无论有没有异常都要执行
-->
<aop:after method="finalAdvice" pointcut-ref="pointcut4"/>
切面中方法书写
public void finalAdvice(){
System.out.println("最终通知=======");
}