【spring 5】AOP:spring中对于AOP的的实现
在前兩篇博客中,介紹了AOP實現的基礎:靜態代理和動態代理,這篇博客介紹spring中AOP的實現。
一、采用Annotation方式
首先引入jar包:aspectjrt.jar && aspectweaver.jar
applicationContext配置文件:
<span style="font-family:KaiTi_GB2312;font-size:18px;"><?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"xmlns:tx="http://www.springframework.org/schema/tx"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsdhttp://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd"><!-- 啟用AspectJ對Annotation的支持 --> <span style="color:#ff0000;"><aop:aspectj-autoproxy/></span> <bean id="user" class="com.angel.spring.User"/><bean id="successfulHandler" class="com.angel.spring.SuccessfulHandler"/></beans>
</span>接口和實現類省略 代理攔截類:
<span style="font-family:KaiTi_GB2312;font-size:18px;">package com.angel.spring;import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;@Aspect
public class SuccessfulHandler {/*** 定義Pointcut,Pointcut的名稱為addAddMethod(),此方法沒有返回值和參數* 該方法就是一個標識,不進行調用*/@Pointcut("execution(* add*(..))")private void addAddMethod(){};/*** 定義Advice,表示我們的Advice應用到哪些Pointcut訂閱的Joinpoint上*///@Before("addAddMethod()")@After("addAddMethod()")private void checkSecurity() {System.out.println("-------Angel,方法執行成功!-------");}
}
</span>通過以上的配置,就可以實現對于方法調用的攔截。我們使用的注解有@Aspect,標記此類是一個橫切面的插入類(攔截類),然后使用@Pointcut,標記我們的攔截方法需要作用于那些地方,最后使用@Before或者@After標記我們的攔截方法是作用于被調用方法前或者后。 但是,通過注解的方式,我們就需要為每個方法都添加注解,如果要修改的話,還得逐一修改,這樣子,雖然同樣輕便,但是如果有一個地方統一配置AOP的話,那就會更為簡便,接下來,我們看第二種實現方式:采用配置方式
二、采用配置方式
applicationContext的配置:<span style="font-family:KaiTi_GB2312;font-size:18px;"><?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"xmlns:tx="http://www.springframework.org/schema/tx"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsdhttp://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd"><!-- 啟用AspectJ對Annotation的支持 --><!-- <aop:aspectj-autoproxy/> --><bean id="user" class="com.angel.spring.User" /><bean id="successfulHandler" class="com.angel.spring.SuccessfulHandler" /><aop:config><aop:aspect id="IsSuccessfulAspect" ref="successfulHandler"><!-- com.bjpowernode.spring包下所有的類所有的方法<aop:pointcut id="addAddMethod" expression="execution(* com.bjpowernode.spring.*.*(..))"/> --><!-- com.bjpowernode.spring包下所有的類的以add和del開頭的方法--><aop:pointcut id="addAddMethod" expression="execution(* com.angel.spring.*.add*(..)) || execution(* com.angel.spring.*.del*(..))" /><aop:before method="checkSecurity" pointcut-ref="addAddMethod" /></aop:aspect></aop:config></beans>
</span>攔截類: <span style="font-family:KaiTi_GB2312;font-size:18px;">package com.angel.spring;import org.aspectj.lang.JoinPoint;public class SuccessfulHandler {private void checkSecurity(JoinPoint joinPoint) {System.out.println("-------Angel,方法執行成功!-------");}
}</span>經過這樣的配置就可以實現方法的攔截了,但有時候,我們不僅需要攔截方法名稱,我們還需要知道,在執行這個方法的時候,用戶到底傳遞了什么樣的參數,那么,我們需要在攔截類采用Advice中添加一個JoinPoint參數,取得客戶端調用的方法名稱及參數值,如:
<span style="font-family:KaiTi_GB2312;font-size:18px;">package com.angel.spring;import org.aspectj.lang.JoinPoint;public class SuccessfulHandler {private void checkSecurity(JoinPoint joinPoint) {for (int i=0; i<joinPoint.getArgs().length; i++) {System.out.println(joinPoint.getArgs()[i]);}System.out.println(joinPoint.getSignature().getName());System.out.println("-------Angel,方法執行成功!-------");}
}</span>三、采用CGLIB代理
以上的例子,我們都是采用JDK的代理實現的AOP,JDK的動態代理是代理的接口,如果有些類并沒有實現接口,那么我們將不得不采用另外一種代理方式:CGLIB動態代理。如:
首先,引入支撐CGLIB的jar包cglib-nodep.jar
其次,在applicationContext配置文件中,強制開啟CGLIB代理:
<span style="font-family:KaiTi_GB2312;font-size:18px;"><!-- 強制使用CGLIB代理 -->
<aop:aspectj-autoproxy proxy-target-class="true" /></span>區別:User類不再實現IUser接口,而是一個單獨的類,代理成功!
四、總結
JDK的動態代理機制只能代理實現了接口的類,而不能實現接口的類就不能實現JDK的動態代理,cglib是針對類來實現代理的,他的原理是對指定的目標類生成一個子類,并覆蓋其中方法實現增強,但因為采用的是繼承,所以不能對final修飾的類進行代理。
對于AOP的總結,到此結束,接下來總結事務的知識點。PS:深刻感覺,之前對于AOP是被嚇退了!
轉載于:https://www.cnblogs.com/hhx626/p/6010307.html
總結
以上是生活随笔為你收集整理的【spring 5】AOP:spring中对于AOP的的实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Jmeter性能测试 入门
- 下一篇: 指针的各式定义