Spring實踐:AOP-Java開發(fā)Java經驗技巧_第1頁
Spring實踐:AOP-Java開發(fā)Java經驗技巧_第2頁
Spring實踐:AOP-Java開發(fā)Java經驗技巧_第3頁
Spring實踐:AOP-Java開發(fā)Java經驗技巧_第4頁
Spring實踐:AOP-Java開發(fā)Java經驗技巧_第5頁
已閱讀5頁,還剩11頁未讀 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、spring實踐:aop-編程開發(fā)技術spring 實踐:aop原文出處:翡青aop引介aop (aspect ori en ted programing)面向切面編程采用橫向抽取機制,以取代傳統(tǒng) 的縱向繼承體系的重復性代碼(如性能監(jiān)控/事務管理/安全檢杳/緩存實現等).橫向抽取代碼復用:基于代理技術,在不修改原來代碼的前提下, 對原有方法進行增強.spring aop 歷史 1.2 開始,spring 開始支持 aop 技術(spring aop)spring aop使用純java實現,不需要專門的編譯過程和類加載器,在運行期通過代理 方式向目標類織入增強代碼. 2.0之后,為了簡化aop開

2、發(fā),spring開始支持aspect;(個基于java的aop框架) 框架.aop相關術語術語 中文描述joinpointpointcutadvice連接 指那些被攔截到的點.在spring中,這些點指方法(因為spring只支持方法 點類型的連接點).切:指需要(配置)被增強的joinpoint.點 通知/指攔截到joinpoint后要做的操作.通知分為前置通知/后置通知/界常通知/ 增強最終通知/環(huán)繞通知零.aspect 切面切入點和通知的結合.target目標對象需要被代理(增強)的對象.proxy代理對象日標對象被aop?織入?增強/通知后產生的對象術語中文描述weaving指把增強/

3、通知應川到目標對象來創(chuàng)建代理對象的過程(spring采川動態(tài) 代理織入,aspect;采用編譯期織入和類裝載期織入).introduction»入一種特殊通知,在不修改類代碼的前提下,可以在運行期為類動態(tài)地添加 引介一些 method/field(不常用).其他關于aop理論知識可參考aop技術研究.aop實現spring aop代理實現冇兩種:jdk動態(tài)代理和cglib框架動態(tài)代理,jdk動態(tài)代 理可以參考博客代理模式的動態(tài)代理部分,在這里僅介紹cglib框架實現.cglib動態(tài)代理cglib(code generation library)是一個開源/高性能/高質量的code生成

4、類庫, 可以在運行期動態(tài)擴展java類與實現java接口.cglib比java. lang, reflect. proxy更強的在于它不僅可以接管接口類的方法, 還可以接管普通類的方法(cglib項口)從3. 2開始,spring-core包屮內置 cglib類,因此可以不用添加額外依賴. userdao(并沒有實現接口)/* author jifang* ©since 16/3/3 上午 11:16.*/public class userdao public void add (object o) system, out. print in ("userdao ->

5、 add: " + o. tostringo);public void get (object o) system, out. println(,zuscrdao -> get: " + o. tostring(); cglibproxyfactorypublic class cglibproxyfactory private object target;public cglibproxyfactory(object target) this. target 二 targct;private callback callback 二 new methodintercep

6、tor() /* ©param obj代理對彖* param method 當期調用方法* param args 方法參數* param proxy被調用方法的代理對象(用于執(zhí)行父類的方法)* ©return* ©throws throwable*/©overridepublic objcc t intc rccp t( objcc to bj,met hod method, objcc t args, methodproxy proxy) throws throwable /前置增強 system, o ut .println(+ before adv

7、ice );/執(zhí)行目標方法/object result = method, invoke(target, args); object result 二 proxy invoke(target, args);/后置增強 system, out. printin(+ after advice );return result;public object createproxy() / 1.創(chuàng)建enhancer對象enhemcor enhemcor 二 new enhemcor ();/ 2. eglib創(chuàng)建代理,對目標對彖創(chuàng)建子對彖 enhancer. setsuperclass(target. g

8、etclass();/ 3.傳入回調接口,對目標增強 enhancer. setcallback(callback);return enhancer.create();public static void main(string args) userdao proxy 二(userdao) new cglibproxyfactory(new userdao (). createproxy ();proxy.gct("hello");proxy. add (z,world,z);aop小結 spring aop的底層通過jdk/cglib動態(tài)代理為目標對象進行橫向織入:1)若

9、目標對象實現了接口,則spring使用jdk的java. lang, reflect. proxy代 理.2)若目標對象沒有實現接口,則spring使用eglib庫生成目標對象的了類. spring只支持方法連接點,不提供屬性連接.標記為final的方法不能被代理,因為無法進行覆蓋.程序應優(yōu)先對針對接口代理,這樣便于程序解耦/維護.spring aopaop 聯(lián)盟為通知 advice 定義了 org. aopalliance. aop. advice 接口,spring 在advice的基礎上,根據通知在目標方法的連接點位置,擴充為以下五類:通知接口ijij 置通知me thodbef ore

10、ad v ice后置通知afterreturn ingadv ice描述在目標方法執(zhí)行麗實施增強執(zhí)行尿施增強.執(zhí)行滋后實施增強異常拋出通知throwsadvicc拋出弄獅實施增強環(huán)繞通知 methodinterceptor引介通知 introductioninterceptor任標類%'添加新的方法和屬性少環(huán) 添加spring的aop依賴使用spring的aop和aspcctj需要在pom.xml中添加如下依賴:<dcpcndcncy><groupld>org. springframework</group1d><artifactid>s

11、pring-aop</artifactid><version>$ spring. version</version></dependency><dcpcndcncy><groupld>org. springframework</group1d> <artifactld>spring-aspects</artifactld> <version>$ spring. version</version></dependency>定義 target/* 

12、9;author jifang* since 16/3/3 下午 2:50.*/public intcrfacc ordcrscrvicc void save ();tnteger delete仃nteger param);public class orderservicelmpl implements orderservice©overridepublic void save() system, out. print in ("添加 );©overridepublic tnteger delete(tnteger param) system, out. prin

13、tin (刪除"); return param;定義 advice*實現method interceptor接口定義環(huán)繞通知* author jifang* since 16/3/6 下午 2:54.*/public class concreteinterceptor implements methodinterceptor ©overridepublic object invoke (methodinvocation invocation) throws throwable system, out. printin (,z前置通知-“);object result 二 i

14、ceedo;system, out. println(,z<-后置通知");return result;spring手動代理配置代理spring最原始的aop支持,手動指定口標對象與通知(沒有使丿ij aop名稱空間).<?xml version二1. 0 encoding二utf-8?><bcans xmlns二http:/www. springframcwork. org/schcma/bcans xmlns:xsi二http:/www. w3. org/2001/xmlschema-instance,zxsi:schemaloc

15、ation二http:/www. springframework. org/schema/beanshttp:/www. springframcwork. org/schcma/bcans/spring-bcans. xsd><!- target -><bean id二service" class二com. fq. service, impl. orderserviceimpl/z/> <!一一 advice 一一><bca n id 二"advice" class=,zcom. fq. advice. concre

16、te in tcrccptor/z/><bean id二serviceproxy"class二org. springframework. aop. framework. proxyfactorybean><property name=target ref二service"/<propcrty namc="intcrccptornamcs/z value二advice"/<property name二proxytargetclass" value二false"/</bean></be

17、ans>clientrunwith(springjuni14c1assrunner. class)contextconfiguration(locations =,zclasspath: spring/applicationcontext. xml") public class aopclient autowircd/必須指定使用代理對象名稱,否則不予代理 ©qualifier (,zserviceproxy/z)private orderservice service;tcstpublic void client() service, save ();service

18、.delete(88);這種方式的缺陷在于每個target都必須手動指定proxyfactorybean對其代理(不能批量指定),而且這種方式會在 spring容器中存在兩份target對象(代理前/代理后),浪費資源, 且容易出錯(比如沒有指定©qualifier).spring自動代理-引入 aspectj通過aspectj引入pointcut切點定義 target/ad vice 同前定義切而表達式?通過execution函數定義切點表達式(定義切點的方法切入)? execution«訪問修飾符返冋類型方法名(參數)異常)? 如:?1) ?execution(publ

19、ic * *()?# 匹配所有 public 方法?2) ?execution(* com. fq. dao. *(.)?#匹配指定包卜所有類方法(不包 含子包)?3) ?execution(* com. fq. dao. .*(.)?#匹配指定包下所有類方法(包含子包)?4)?execution(v com. fq. service, impl. orderservicetmple. *( )?#匹配指定類所有方法?5)?execution (耳c com. fq. service. orderservice+. *(.)?# 匹配實現特定接口所有類方法?6)?execution g:sav

20、e* ( ) ?#匹配所有save開頭的方法<?xml version二"1. 0 encoding二utf-8"?><beans xmlns=/h11p: /www. springframework org/schenia/bedns"xmlns:xsi二http:/www. w3. org/2001/xmlschema-instancexml ns: aop=/zhttp:/wvv. springframework. org/schema/aop/zxsi:schemalocation二http:/www. springframework.

21、org/schema/beanshttp:/www. springframework. org/schema/beans/spring-beans. xsdhttp:/www. springframework. org/schema/aophttp:/www. springframework. org/schema/aop/spring-aop. xsd><!- target -><bean id二service" class=/zcom. fq. service, impl. orderserviceimprz/> <!一一 advice 一一&

22、gt;<bean id二advice" cl ass二com. fq. advice. concretetnterceptor/><!- 配置切而:proxy-target-class 確定是否使用 cgl1b -> <aop: config proxy-target-class=/true/z><! aop:pointcut : 切點定義aop:advisor:定義spring傳統(tǒng)aop的切面,只支持一個poi nt cut/個 adviceaop:aspect :定義aspectj切面的,可以包含多個pointcut/多個 advice&

23、gt;<aop:pointcut id=pointcut expression二cxccution(*com. fq. service, impl. orderservicelmpl. *() /><aop:advisor advice-ref=,zadvice/z pointcut-ref二pointcut/> </aop:config></beans> client 同前aspectj aopaspectj是一個基于java的aop框架,提供了強大的aop功能,其他很多a0p框 架都借鑒或采納了 aspectj的一些思想,spring2. 0

24、以后增加了對aspectj切點 表達式支持(如上),并在spring3. 0之后與aspectj進行了很好的集成.在java領域,aspectj中的很多語法結構基本上已成為aop領域的標準,他定義 了如下幾類通知類型:通知接口描述前置通知©before相當于beforeadvice后置通知afterreturning相當于 afterreturningadvice環(huán)繞通知around相當于 methodinterceptor拋出通知afterthrowing相當于 throwadvice引介通知dcclarcparcnts相當于 introductioninterceptor最終fi

25、nal通知©after不管是否界常,該通知都會執(zhí)行新版本spring,建議使用aspectj方式開發(fā)以簡化a0p配置.aspectj-xml-aop使用aspectj編寫advice無需實現任何接口,而且可以將多個通知寫入一個切面 類.前置通知定義通知/* author jifang* ©since 16/3/3 下午 5:38.*/public class aspect /*無返回值*/public void beforel() system, out. printin (前置增強 beforel");/*還可以傳入連接點參數joinpoinl* param p

26、oint*/public void before2(joinpoint point) system, out. printf (前置增強 before2 %s%n, point. getkind (); 裝配<?xml version二"1. 0 encoding二utf-8"?><beans xmlns=/h11p: /www. springframework org/schenia/bedns" xmlns:xsi二http:/www. w3. org/2001/xmlschema-instance xml ns: aop=/zhttp:/w

27、vv. springframework. org/schema/aop/zxmlns:context二http:/www. springframework. org/schema/context"xsi: schemalocation=/zhttp:/www. springframework, org/schema/beanshttp:/www. springframework. org/schema/beans/spring-beans.xsdhttp:/www. springframework org/schema/dophttp:/www. springframework. o

28、rg/schema/aop/spring-aop. xsd http:/www. springframework. org/schema/contexthttp:/www. springframework. org/schema/context/spring-context xsd><context:component-scan base-package二com. fq. service"/<!-配置切面通知-<bean id二advice" class二com. fq. advice. aspect"/<! aop切面配置一>

29、<aop:co nf iq<aop:aspect rcf=,/advicc,><aop:pointcut id二pointeexpression二execution(* com. fq. service, impl. 0rderserviceimp 1. *( )/><aop:before method二beforel" pointcutref=/zpointcut/> <aop:before method二before2 pointcut-ref二pointcut/> </aop:aspcct></aop:co

30、nfig></beans>前置通知小結o前置通知會保證在n標方法執(zhí)行前執(zhí)行;o詢置通知默認不能阻止目標方法執(zhí)行(但如果通知拋出界常,則目標方法無法 執(zhí)行);o可以通過joinpoint參數獲得當前攔截對象和方法等信息.后置通知定義通知public void afterreturning(joinpoint point, object result) system, out. printf (,z后置增強,結果為 s%n,result);裝配<aop:after-returning method二"aftcrrctuiming” returning二"

31、result" pointcut-ref二pointcut"/>后置通知可以獲得方法返冋值,但在配置文件定義返冋值參數名必 須與后置通知方法參數名一致(如result).環(huán)繞通知定義通知public object around(proceedingjoinpoint point) throws throwable system, out. printf 環(huán)繞前置增強 method: %s, args: %s%n, point, to shor tstring (), arrays. tostr ing (po int. get args ();object resul

32、t = point, proceed (point. getargso);system, out. printf (?,環(huán)繞后置增強 result: %s%n: result);return result;<aop:around method=,/around/z arg-names二point" pointcut-ref 二 pointcut 7環(huán)繞通知口j以實現任何通知的效果,甚至口j以阻止b標方法的執(zhí) 行.拋岀通知定義通知private static final logger logger =loggcrfactor). get logger (aspect, class

33、);public void afterthrowing(joinpoint point, throwable ex) string message 二 new str in gbui ider (/zmethod) append(point呂etsignature (). getname (). append(“ crrorz/). tostring();system, out. printin(message);logger, error (“ ,“,message, ex);裝配<aop:after-throwing method二afterthrowing" throwi

34、ng二ex pointcut-ref=/zpointcut,z/>throwing屬性指定異常對象名,該名稱應和方法定義參數名 致.最終通矢口定義通知public void after(joinpoint point) system, out. println(,/最終通知,釋放資源);<aop:after method=,zafterzz pointcut-ref=/pointcut/z/>無論口標方法是否出現異常,該通知都會執(zhí)行(類似finally代碼 塊,應用場景為釋放資源).aspectj-annotation-aopaspectj是aspectj 1. 5新增功能,

35、可以通過jdk注解技術,直接在bean類中定 義切面.aspectj預定義的注解有:bcforc/afterreturning/around/aftcrthrowing/declarcparcnts/af ter.描述同前.使用aspectj注解aop需要在applicationcontext, xml文件中開啟注解自動代 理功能:<?xml version二1. 0 encoding二utf-8?><bcans xmlns二http:/www. springframework. org/schcma/bca xmlns:xsi二http:/www. w3. org/2001

36、/xmlschema-instance,z xmlns: nop二http:/www. springframework org/schema/aop/z xmlns:context=http:/www. springframework. org/schema/contextxsi:schcmalocation二http:/www. springframework. org/schcma/bcanshttp:/www. springframework, org/schema/beans/spring-beans, xsdhttp:/www. springframework. org/schcma

37、/aop http:/www. springframework. org/schema/aop/spring-aop. xsd http:/www. springframework. org/schema/contexthttp:/www. springframework. org/schema/context/spring-context. xsd><!- 批量掃描©component -><context:component-scan base-package二com. fq/><!啟用注解自動代理aspect><aop:aspec

38、tj-autoproxy/> </beans> orderservice/client 同前before aspect/* aspect:指定是一個切面* ©component:指定口j以被spring容器掃描到*/©aspect©component public class customaspect bcforc("execution(*com. fq. service, impl. orderservicelmpl. *() public void before(joinpoint point) system, out. print

39、f (前置增強 before2 %s%n, point. getkind (); afterreturningafterreturning(value = "execution(*com. fq. service, impl. orderservicelmpl. d* (.)returning = "result") public void afterreturning(joinpoint point, object result) system, out. printf c后置增強,結果為 s%n,result);around©around("execution(* com fq. service, impl. orderservicelmpl. *() public object around(proceedingjoinpoint point) throws throwable long start = system. currentt

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論