关于SpringAOP的XML方式的配置
AOP(XML)【理解】【應用】【重點】
?????? 1.AOP基礎實例
A.導入jar包
???????????????????? 核心包(4個)???????? 日志(2個)???????????? AOP(4個)
???????????????????? Spring進行AOP開發(1個)(3.2資源包)
spring-aop-3.2.0.RELEASE.jar
Spring整合AspectJ框架(3.2資源包)
spring-aspects-3.2.0.RELEASE.jar
AOP聯盟規范(1個) (3.0.2依賴包)
com.springsource.org.aopalliance-1.0.0.jar
aspectJ支持(1個) (3.0.2依賴包)
com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
B.制作目標對象類(配置成Bean)
????????????? public class UserImpl {?
????????????? //當前類的三個方法中具有共性功能System.out.println("共性功能1");? 抽取出來
?????? ?????? public void add(){
???????????????????? //共性功能1被抽取走了,放入到了MyAdvice類中的functionOne方法里
???????????????????? System.out.println("共性功能2");
?????? ????????????? System.out.println("user add....");
?????? ?????? }
}
注意:共性功能被抽取后,不是在原始位置進行調用,而是將共性功能刪除
????????????? C.將抽取的功能制作成通知(配置成Bean)
???????????????????? public class MyAdvice {??????
????????????? //被抽取的共性功能1
?????? ?????? public void functionOne(){
???????????????????? System.out.println("共性功能1");
?????? ?????? }????
}
說明:被抽取的共性功能制作成獨立的類中方法。由于要將兩個對象中的內容融合,Spring在控
制其融合的過程必須控制兩個對象,因此需要分別將兩個類配置為Spring管理的Bean
????????????? D.開啟AOP空間的支持
???????????????????? <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
?????? ?????? ?????? ">
?????? ?????? E.配置AOP的切面
????????????? ?????? <!-- 配置AOP -->
?????? ?????? <aop:config>
?????? ?????? ?????? <!-- 配置切面,指定切面類的Bean:配置切入點與通知之間的關系 -->
?????? ????????????? <!-- ref:配置切面對應的Bean -->
?????? ????????????? <aop:aspect ref="myAdvice">
?????? ?????? ????????????? ?????? <!-- 聲明通知的類別是何種類型? 前置通知-->
<!-- 配置前置通知 -->
?????????????????????????????????? <!-- aop:before表示在原始方法執行前追加功能 -->
?????????????????????????????????? <!-- pointcut:配置Spring監控的方法切入點 -->
??????????????????????????? <!-- method:配置的切面類中對應的共性功能-方法名稱 -->
?????? ?????? ????????????? <aop:before pointcut="execution(* cn.itcast.aop.one.UserImpl.add())" method="functionOne"/>
?????? ????????????? </aop:aspect>
?????? ?????? </aop:config>
????????????? F.制作Spring格式的客戶端程序測試
???????????????????? ApplicationContext ctx = new ClassPathXmlApplicationContext(“applicationContext.xml”);
UserDao dao = (UserDao)ctx.getBean(“userDao”);
dao.add();
?????? 2.切入點表達式
格式:execution(切入點表達式)
?????? ?????? execution([方法的訪問控制修飾符] 方法的返回值 包名.類名/接口名.方法名(參數))
?????? ?????? 注意:方法的訪問控制修飾符可以省略
????????????? 范例:
public void cn.itcast.UserDAO.add()??? 公共的cn.itcat包中的UserDAO類的無參數無返回值的add方法
void cn.itcast.UserDAO.add()???????????????????? 公共的cn.itcat包中的UserDAO類的無參數無返回值的add方法
?????? ?????? 方法的返回值可以寫具體的返回值,或者寫*表示任意返回值
????????????? void cn.itcast.UserDAO.add()?????? 公共的cn.itcat包中的UserDAO類的無參數無返回值的add方法
????????????? * cn.itcast.UserDAO.add()??? 公共的cn.itcat包中的UserDAO類的無參數不限定返回值的add方法
?????? ?????? 包名,方法名
????????????? * cn.itcast.*.dao.UserDAO.add()?? cn包下的itcast包下的任意包下的dao包下的…..
????????????? * cn.itcast..dao.UserDAO.add()??? cn包下的itcast包下的任意層包下的dao包下的…..
????????????? * *..*.*() ?????????????????????????????????? 任意包下的任意類中的任意方法
?????? ?????? 參數
????????????? add()????????????? 無參數
????????????? add(*)??????????? 一個參數
????????????? add(int)????????? 一個int型參數
????????????? add(*,*)???????? 兩個參數
????????????? add(*,int)????????????? 兩個參數,第一個任意,第二個int
????????????? add(..)??????????? 任意參數
????????????? add(*,..)???????? 至少一個參數
?????? ?????? 特殊格式:
????????????? * cn.itcast.UserDAO.add(..) && args(int,int)???????????? ???????????????????? 錯誤
????????????? * cn.itcast.UserDAO.add(..)? &&? args(int,int)??????? 正確
????????????? * cn.itcast.UserDAO.add(int,int)? &&? args(a,b)????? 不常用,正確
????????????? * cn.itcast.UserDAO.add(int,int)? &&? args(b,a)????? 不常用,正確
?????? 3.切入點配置方式
切入點配置時,可以設置切面間共享切入點,也可以設置切面內共享切入點,還可以設置局部切入點
??? 格式一:配置在通知類別后面
?????????? <aop:before? ?pointcut="execution(public void *..*.*Impl.a*())"? ….
格式二:配置在某個切面中,在當前切面范圍內共享
??? <aop:aspect ref="myAdvice">
????????????????? <!-- 配置同一個切面中使用的公共切入點 -->
????????????????? <aop:pointcut expression="execution(public void *..*.*Impl.a*())" id="pt2"/>
????????????????? <aop:before ??pointcut-ref="pt2" …..
??? 格式三:配置在AOP總配置中,在全部范圍內共享
?????????? <aop:config>
?????????? ?????? <aop:pointcut expression="execution(public void *..*.*Impl.a*())" id="pt1"/>
??? ????????????? <aop:aspect ref="myAdvice">
??? ?????? ????????????? <aop:before pointcut-ref="pt1"……
????????????????? </aop:aspect>
?????????? </aop:config>
范例:
<aop:config>
?????? ?????? ?????? <!-- 所有切面共享的切入點 -->
?????? ????????????? <aop:pointcut expression="execution(* cn.itcast..*Tar*.*())" id="pt"/>
?????? ????????????? <aop:aspect ref="myAdvice">
?????? ?????? ????????????? <!-- 在一個切面內共享的切入點:配置獨立的切入點表達式對象 -->
????????????? ?????? ?????? <aop:pointcut expression="execution(* cn.itcast..*Tar*.*(..))" id="pt1"/>
????????????? ?????? ?????? <aop:before pointcut-ref="pt" method="fn"/>
????????????? ?????? ?????? <aop:before pointcut="execution(* *..*.*(..))" method="fn"/>
?????? ?????? ?????? </aop:aspect>
?????? ?????? ?????? <aop:aspect ref="myAdvice">
?????? ?????? ????????????? <!-- 配置獨立的切入點表達式對象 -->
?????? ?????? ????????????? <aop:pointcut expression="execution(* cn.itcast..*Tar*.*(..))" id="pt2"/>
?????? ?????? ????????????? <aop:before pointcut-ref="pt" method="fn"/>
?????? ?????? ????????????? <aop:before pointcut-ref="pt" method="fn"/>
?????? ?????? ?????? </aop:aspect>
?????? ?????? </aop:config>
?????? 4.通知類別
????????????? 通知共有五種類別
before:在原始操作前運行
?????? after: 在原始操作后運行,無論方法是否拋出異常
?????? afterReturning:在原始操作后運行,只有方法正常結束才運行,拋出異常則不運行
?????? afterThrowing:在原始操作中如果拋出異常,運行
?????? around: 在原始操作前后運行,通過ProceedingJoinPoint對象調用procee()方法完成對原始操作的調用
????????????? //環繞通知
public void around(ProceedingJoinPoint pjp) throws Throwable{
??? System.out.println("around before......");
??? //調用原始方法
??? pjp.proceed();
??? System.out.println("around after......");
}
????????????? 通知的配置格式
?????? ?????? <aop:before pointcut-ref="pt2" method="before"/>
????????????? <aop:after pointcut-ref="pt2" method="after"/>
????????????? <aop:after-returning pointcut-ref="pt2" method="afterReturning"/>
????????????? <aop:after-throwing pointcut-ref="pt2" method="afterThrowing"/>
????????????? <aop:around pointcut-ref="pt2" method="around"/>
?????? 5.通知順序
????????????? 在切入點之前運行的通知
???????????????????? 執行允許與配置順序有關,在上面的先運行
????????????? 在切入點之后運行的通知
???????????????????? 在同一個切面中
??????????????????????????? 執行允許與配置順序有關,在上面的先運行
???????????????????? 在不同的切面中
????????????? ????????????? 執行允許與配置順序有關,與切面的配置順序相反
????????????? 總結:不同通知類型執行的順序以配置順序為準
?????? 6.獲取通知參數
????????????? 為環繞通知之外的通知方法定義形參JoinPoint,該參數必須是通知方法的第一個參數
???????????????????? 獲取參數:Obejct[] args = jp.getArgs();????
???????????????????? 范例:
???????????????????? public void before(JoinPoint jp){??????
????????????? ????????????? Object[] objs = jp.getArgs();
????????????? ????????????? System.out.println("before......"+objs[0]+","+objs[1]);
?????? ????????????? }
????????????? 為環繞通知方法定義形參ProceedingJoinPoint對象
???????????????????? 獲取參數:Obejct[] args = pjp.getArgs();
?????? 7.獲取通知返回值
????????????? afterReturning 與 around可以獲取方法的返回值
????????????? A.around通知獲取返回值
???????????????????? ProceedingJoinPoint對象執行調用原始操作的返回值就是原始方法的運行返回值
???????????????????? Object res = pt.proceed(args);
???????????????????? 注意:如果原始方法返回值為void類型,則around方法返回值設置為Object
如果原始方法返回值為非void類型,則around方法內必須將原始方法調用的結果返回
原始方法返回值為void類型的,通知內獲取的返回值統一為null
???????????????????? public Object around(ProceedingJoinPoint pjp) throws Throwable{
??????????????????????????? Object res = pjp.proceed(args);
??????????????????????????? return res;
???????????????????? }
????????????? B.afterReturning通知獲取返回值
???????????????????? 在通知方法的參數中,聲明一個Object類型的參數,用于保存方法的返回值
???????????????????? public void afterReturning(JoinPoint jp,Object abc){
?????? ?????? ?????? ?????? System.out.println("afterReturning......"+ abc);
?????? ?????? ?????? }
???????????????????? 在配置文件中,為afterReturning聲明保存返回值的變量名
???????????????????? <aop:after-returning ?method="afterReturning" returning="abc"/>
?????? 8.獲取通知異常對象
異常對象的獲取方式與返回值很相似,聲明變量,在配置中聲明保存異常對象的變量名
????????????? <aop:after-throwing pointcut-ref="pt" method="afterThrowing" throwing="e"/>
????????????? public void afterThrowing (Throwable e){
?????? ????????????? System.out.println("afterThrowing......."+ e);
????????????? }
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的关于SpringAOP的XML方式的配置的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: (二)线程同步_3---在类中使用相互独
- 下一篇: dwz ajax session超时跳转