




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
事務(wù)是一組操作的集合,它是一個不可分割的工作單位。事務(wù)會把所有的操作作為一個整體,一起向數(shù)據(jù)庫提交或者是撤銷操作請求。所以這組操作要么同時成功,要么同時失敗。怎么樣來控制這組操作,讓這組操作同時成功或同時失敗呢?此時就要涉及到事務(wù)的具體操作了。事務(wù)的操作主要有三步:開啟事務(wù)(一組操作開始前,開啟事務(wù)):starttransaction/begin提交事務(wù)(這組操作全部成功后,提交事務(wù)):commit;回滾事務(wù)(中間任何一個操作出現(xiàn)異常,回滾事務(wù)):rollback;簡單的回顧了事務(wù)的概念以及事務(wù)的基本操作之后,接下來我們看一個事務(wù)管理案例:解散部門(解散需求:當部門解散了不僅需要把部門信息刪除了,還需要把該部門下的員工數(shù)據(jù)也刪除了。步驟:33456789publicclassDeptServiceImplimplements{privateDeptMapperprivateEmpMapperpublicvoiddelete(Integer//根據(jù)部門id刪除部門信息}}1123456789publicinterfaceDeptMapper*根據(jù)id刪除部門信息*@param@Delete("deletefromdeptwhereid=#{id}")voiddeleteById(Integerid);部門}112345678publicinterfaceEmpMapper//根據(jù)部門id刪除部門下所有員工@Delete("deletefromempwherepublicintdeleteByDeptId(Integer}1123456789publicclassDeptServiceImplimplements{privateDeptMapperprivateEmpMapper//根據(jù)部門id,刪除部門信息及部門下的所有員工publicvoiddelete(Integer//根據(jù)部門id刪除部門信息inti=}}成了數(shù)據(jù)的不一致。先執(zhí)行根據(jù)id刪除部門的操作,這步執(zhí)行完畢,數(shù)據(jù)庫表dept中的數(shù)據(jù)就已經(jīng)刪除了。執(zhí)行1/0操作,拋出異常執(zhí)行。而要想保證操作前后,數(shù)據(jù)的一致性,就需要讓解散部門中涉及到的兩個業(yè)務(wù)操作,要么全部成功,要么全部失敗。那我們?nèi)绾?,讓這兩個操作要么全部成功,要么全部失敗呢?在方法運行之前,開啟事務(wù),如果方法成功執(zhí)行,就提交事務(wù),如果方法執(zhí)行的過程當中出現(xiàn)異常了,就回滾事務(wù)。@Transactional@Transactional@Transactional類接口下所有的實現(xiàn)類當中所有的方法都交給spring接下來,我們就可以在業(yè)務(wù)方法delete上加上@Transactional來控制事務(wù)。1123456789publicclassDeptServiceImplimplements{privateDeptMapperprivateEmpMapper//publicvoiddelete(Integer//根據(jù)部門id刪除部門信息//inti=//刪除部門下的所有員工信息}}在業(yè)務(wù)功能上添加@Transactional注解進行事務(wù)管理后,我們重啟SpingBoot服務(wù),使用n測試:說明:可以在aplication.ml配置文件中開啟事務(wù)管理日志,這樣就可以在控制看到和事務(wù)相關(guān)的日志信息了#spring#spring事務(wù)管理日志org.springframework.jdbc.support.JdbcTransactionManager:前面我們通過sping事務(wù)管理注解@Tranactional已經(jīng)控制了業(yè)務(wù)層方法的事務(wù)。接下來我們要來詳細的介紹一下@Tranactinal事務(wù)管理注解的使用細節(jié)。我們這里主要介紹@Tansactional注解當中的兩個常見的屬性:1123456789publicvoiddelete(Integer//根據(jù)部門id刪除部門信息inti=}以上業(yè)務(wù)功能deete()方法在運行時,會除0的算數(shù)運算異常(運行時異常),出現(xiàn)異常之后,由于我們在方法上加了@Trnsactonal注解進行事務(wù)管理,所以發(fā)生異常會執(zhí)行rollbck回滾操作,從而保證事務(wù)操作前后數(shù)據(jù)是一致的。下面我們在做一個測試,我們修改業(yè)務(wù)功能代碼,在模擬異常的位置上直接拋出Excetion異常(時異常)12123456789publicvoiddelete(Integerid)throwsException//根據(jù)部門id刪除部門信息//thrownewException("出現(xiàn)異常了}//刪除部門下的所有員工信息}說明:在servie中向上拋出一個Excepion編譯時異常之后,由于是controller調(diào)用sevice,所以在controller中要有異常處理代碼,此時我們選擇在contrller常向上拋。3//4("根據(jù)id刪除部門5//調(diào)用service678return9}1212publicResultdelete(@PathVariableIntegerid)throwsException通過以上測試可以得出一個結(jié)論:默認情況下,只有出現(xiàn)RuntieExcption(運行時異常)事務(wù)。1123456789publicclassDeptServiceImplimplementsDeptService{privateDeptMapperprivateEmpMapperpublicvoiddelete(Integerid){//根據(jù)部門id刪除部門信息//intnum=//刪除部門下的所有員工信息} 在Spring的事務(wù)管理中,默認只有運行時異常RuntimeException才會回滾。我們接著繼續(xù)學習@Transactional注解當中的第二個屬性propagation的行為的。例如:兩個事務(wù)方法,一個A方法,一個B方法。在這兩個方法上都添加了@Transactional表這兩個方法都具有事務(wù),而在A方法當中又去調(diào)用了B方法。所謂事務(wù)的行為,指的就是在A方法運行的時候,首先會開啟一個事務(wù),在A方法當中又調(diào)用了B方法,B方法自身也具有事務(wù),那么B方法在運行的時候,到底是加入到A方法的事務(wù)當中來,還是B在運行的時候新建一個事務(wù)?這個就涉及到了事務(wù)的行為。propagation屬性來指定行為。接下來我們就來介紹一下常見的事務(wù)行為… 由于解散部門是一個非常重要而且非常的操作,所以在業(yè)務(wù)當中要求每一次執(zhí)行解散部門的操作都需要留下痕跡,就是要記錄操作日志。而且還要求無論是執(zhí)行成功了還是執(zhí)行失敗了,都需要留下痕跡。創(chuàng)建數(shù)據(jù)庫表dept_logcreatecreatetableidintauto_incrementcomment'主鍵ID'primarycreate_timedatetimenullcomment'操作時間descriptionvarchar(300)nullcomment'操作描述)comment'部門操作日志表publicclassDeptLogprivateIntegerprivateLocalDateTimeprivateString publicinterface{4567@Insert("insertintodept_log(create_time,description)voidinsert(DeptLog}publicpublicinterfaceDeptLogServicevoidinsert(DeptLog 1123456789publicclassDeptLogServiceImplimplementsDeptLogServiceprivateDeptLogMapper@Transactional//事務(wù)行為:有事務(wù)就加入、沒有事務(wù)就新建事務(wù)publicvoidinsert(DeptLog{}}45645678publicclassDeptServiceImplimplements{privateDeptMapper123制//當前業(yè)務(wù)實現(xiàn)類中的所有的方法,都添加了spring事務(wù)管理機 privateEmpMapperempMapper;privateDeptLogServicedeptLogService;//根據(jù)部門id@Transactional(rollbackFor=publicvoiddelete(Integerid)throwsExceptiontry//根據(jù)部門id刪除部門信息//模擬:異常thrownewException("出現(xiàn)異常了 //}finally//不論是否有異常,最終都要執(zhí)行的代碼:記錄日志DeptLogdeptLog=new deptLog.setDescription("執(zhí)行了解散部門的操作,此時解散的是"+id+"號部門");// //省略其他代碼 執(zhí)行了刪除3號部門操作執(zhí)行了插入部門日志操作當執(zhí)行insert操作時,inset設(shè)置的事務(wù)行是默認值REQUIRED表有務(wù)就入,有則新建事務(wù)此時:delete和inset操作使用了同一個事務(wù),同一個事務(wù)中的多個操作,要么同時成功,要么同時失敗,所以當異常發(fā)生時進行事務(wù)回滾,就會回滾deete和inset操作在DeptLogServiceImpl類中insert方法上,添加@Transactional(propagationPropagation.REQUIRES_NEWPropagation.REQUIRES_NEW1234567publicclassDeptLogServiceImplimplementsDeptLogServiceprivateDeptLogMapper@Transactional(propagation=Propagation.REQUIRES_NEW)//事務(wù)行為:不論是否有事務(wù),都新建事務(wù)89publicvoidinsert(DeptLog{}}那此時,DeptServiceImpl中的delete方法運行時,會開啟一個事務(wù)。當調(diào)用deptLogService.insert(deptLog)時,也會創(chuàng)建一個新的事務(wù),那此時,當insert方法運行完畢之后,事務(wù)就已經(jīng)提交了。即使外部的事務(wù)出現(xiàn)異常,內(nèi)部已經(jīng)提交的事務(wù),也不會回滾了,因REQUIREDREQUIRED:大部分情況下都是用 REQUIRES_NEWREQUIRES_NEW:當我們不希望事務(wù)之間相互影響時,可以使用該 學習完spring的事務(wù)管理之后,接下來我們進入到AOP的學習。AOP也是spring框架的第二大,在AOP基礎(chǔ)這個階段,我們首先介紹一下什么是AOP,再通過一個快速程序,讓大家快速體驗AOP程序的開發(fā)。最后再介紹AOP當中所涉及到的一些的概念。AOP英文全稱:AspectOrientedProgramming(面向切面編程、面向方面編程),其實說白那什么又是面向方法編程呢,為什么又需要面向方法編程呢?來我們舉個例子做一個說明:比如,我們這里有一個項目,項目中開發(fā)了很多的業(yè)務(wù)功能。然而有一些業(yè)務(wù)功能執(zhí)行效率比較低,執(zhí)行耗時較長,我們需要針對于這些業(yè)務(wù)方法進行優(yōu)化。那首先可能多數(shù)人首先想到的就是在每一個業(yè)務(wù)方法運行之前,記錄這個方法運行的開始時間。在這個方法運行完畢之后,再來記錄這個方法運行的結(jié)束時間。拿結(jié)束時間減去開始時間,不就是這個方法的執(zhí)行耗時嗎?個業(yè)務(wù)模塊又包含很多增刪改查的方法,如果我們要在每一個模塊下的業(yè)務(wù)方法中,添加記錄開始時間、AOPAOP的作用:在程序運行期間在不修改源代碼的基礎(chǔ)上對已有方法進行增強(無侵入性:解耦我們要想完成統(tǒng)計各個業(yè)務(wù)方法執(zhí)行耗時的需求,我們只需要定義一個模板方法,將記錄方法執(zhí)行耗時這一部分公共的邏輯代碼,定義在模板方法當中,在這個方法開始運行之前,來記錄這個方法運行的開始時間,在方法結(jié)束運行的時候,再來記錄方法運行的結(jié)束時間,中間就來運行原始的業(yè)務(wù)方法。而中間運行的原始業(yè)務(wù)方法,可能是其中的一個業(yè)務(wù)方法,比如:我們只想通過部門管理的list方法的執(zhí)行耗時,那就只有這一個方法是原始業(yè)務(wù)方法。而如果,我們是先想統(tǒng)計所有部門管理的業(yè)務(wù)方法執(zhí)行耗時,那此時,所有的部門管理的業(yè)務(wù)方法都是原始業(yè)務(wù)方法。那面向這樣的指定的一個或多個方法進行編程,我們就稱之為面向切面編程。那此時,當我們再調(diào)用部門管理的list業(yè)務(wù)方法時啊,并不會直接執(zhí)行l(wèi)ist方法的邏輯,而是會執(zhí)行我們所定義的模板方法,然后再模板方法中:運行原始的業(yè)務(wù)方法(那此時原始的業(yè)務(wù)方法,就是list方法)不論,我們運行的是那個業(yè)務(wù)方法,最后其實運行的就是我們定義的模板方法,而在模板方法中,就完成了原始方法執(zhí)行耗時的統(tǒng)計操作。(那這樣呢,我們就通過一個模板方法就完成了指定的一個或多個業(yè)務(wù)方法執(zhí)行耗時的統(tǒng)計)對了,就是和我們之前所學習的動態(tài)技術(shù)是非常類似的。我們所說的模板方法,其實就是對象中所定義的方法,那對象中的方法以及根據(jù)對應(yīng)的業(yè)務(wù)需要,完成了對應(yīng)的業(yè)務(wù)功能,當運行原其實,AOP面向切面編程和OOP面向?qū)ο缶幊桃粯?,它們都僅僅是一種編程思想,而動態(tài)技術(shù)是這種思想最主流的實現(xiàn)方式。而Sping的AOP是Spring框架的高級技術(shù),旨在管理bean對象的過程中底層使用動態(tài)機制,對特定的方法進行編程(功能增強)。在了解了什么是AOP后,我們下面通過一個快速程序,體驗下AOP的開發(fā),并掌握Spring中AOP的開發(fā)步驟。@Aspect//當前類為切面類publicclass{6789@Around("execution(*com.itheima.service.*.*(..))")publicObjectrecordTime(ProceedingJoinPointpjp)throwsThrowable//longbegin=//執(zhí)行原始方法Objectresult=//longend=(pjp.getSignature()+"執(zhí)行耗時:{}毫秒",end-return}}我們通過AOP程序完成了業(yè)務(wù)方法執(zhí)行耗時的統(tǒng)計,那其實AOP功能不止此,見的用場景如下:事務(wù)管理:我們前面所講解的Spring事務(wù)管理,底層其實也是通過AOP來實現(xiàn)的,只要添加@Tansactionl注解之后,AOP程序自動會在原始方法運行前先來開啟事務(wù),在原始方法運行完畢之后提交或回滾事務(wù)代碼無侵入:沒有修改原始的業(yè)務(wù)方法,就已經(jīng)對原始的業(yè)務(wù)方法進行了功能的增強或者是功能的改變通過SpringAOP的快速,感受了一下AOP面向切面編程的開發(fā)方式。下面我們再來學習AOP及到的一些概念。連接點指的是可以被aop控制的方法。例如:程序當中所有的業(yè)務(wù)方法都是可以被aop的方法。在SprinAOP提供的JoinPont當中,封裝了連接點方法在執(zhí)行時的相關(guān)信息。(的講解)在程序中是需要統(tǒng)計各個業(yè)務(wù)方法的執(zhí)行耗時的,此時我們就需要在這些業(yè)務(wù)方法運行開始之前,先記錄這個方法運行的開始時間,在每一個業(yè)務(wù)方法運行結(jié)束的時候,再來記錄這個方法運行的結(jié)束時間。但是在AOP面向切面編程當中,我們只需要將這部分重復(fù)的代碼邏輯抽取出來單獨定義。抽取出來的這一部分重復(fù)的邏輯,也就是共性的功能。在通知當中,我們所定義的共性功能到底要應(yīng)用在哪些方法上?此時就涉及到了切入點t概念。切入點指的是匹配連接點的條件。通知僅會在切入點方法運行時才會被應(yīng)用。假如:切入點表達式改為DepterviceImp.list(),此時就代表僅僅只有l(wèi)istlit()方法在運行的時候才會應(yīng)用通知。當通知和切入點結(jié)合在一起,就形成了一個切面。通過切面就能夠描述當前aopAOP的概念我們介紹完畢之后,接下來我們再來分析一下我們所定義是如何與目標對象結(jié)合Sping的AOP底層是基于動態(tài)技術(shù)來實現(xiàn)的,也就是說在程序運行的時候,會自動的基于動態(tài)技術(shù)為目標對象生成一個對應(yīng)的對象。在對象當中就會對目標對象當中的原始方法進行功能的增強。@Around(@Around("execution(*publicObjectrecordTime(ProceedingJoinPointpjp)throwsThrowable//longbegin=//執(zhí)行原始方法Objectresult=//longend=//(pjp.getSignature()+"執(zhí)行耗時:{}毫秒",end-return @After:后置通知,此注解標注方法在目標方法后被執(zhí)行,無論是否有異常都會執(zhí)行@AfterReturning:返回后通知,此注解標注方法在目標方法后被執(zhí)行,有異常不會執(zhí)行@AfterThrowing:異常后通知,此注解標注方法發(fā)生異常后執(zhí)行1123456789publicclassMyAspect1//@Before("execution(*com.itheima.service.*.*(..))")publicvoidbefore(JoinPointjoinPoint){("before}//@Around("execution(*publicObjectaround(ProceedingJoinPointproceedingJoinPoint)throwsThrowable{("aroundbefore//調(diào)用目標對象的原始方法執(zhí)行Objectresult=//原始方法如果執(zhí)行時有異常,環(huán)繞通知中的后置代碼不會在執(zhí)行了("aroundafter...");return}//@After("execution(*com.itheima.service.*.*(..))")publicvoidafter(JoinPointjoinPoint){("after}//返回后通知(程序在正常執(zhí)行的情況下,會執(zhí)行的后置通知}}@AfterReturning("execution(*com.itheima.service.*.*(..))")publicvoidafterReturning(JoinPointjoinPoint){("afterReturning}//異常通知(程序在出現(xiàn)異常的情況下,執(zhí)行的后置通知publicvoidafterThrowing(JoinPoint 修改DeptServiceImpl業(yè)務(wù)實現(xiàn)類中的代碼:添加異常 223456789publicclassDeptServiceImplimplements{privateDeptMapperpublicList<Dept>list()List<Dept>deptList=intnum=return}//省略其他代碼}@Around環(huán)繞通知需要自己調(diào)用ProceedingJoinPceed()來讓原始方法執(zhí)行,其1123456789//@Before("execution(*//@Around("execution(*//@After("execution(*//返回后通知(程序在正常執(zhí)行的情況下,會執(zhí)行的后置通知)//異常通知(程序在出現(xiàn)異常的情況下,執(zhí)行的后置通知)我們發(fā)現(xiàn)啊,每一個注解里面都指定了切入點表達式,而且這些切入點表達式都一模一樣。此時我們的代碼當中就存在了大量的重復(fù)性的切入點表達式,假如此時切入點表達式需要變動,就需要將所有的切入點表達式一個一個的來改動,就變得非常繁瑣了。怎么來解決這個切入點表達式重復(fù)的問題?答案就是:Spring提供了@PointCut注解,該注解的作用是將公共的切入點表達式抽取出來,需要用到時該1123456789publicclassMyAspect1//切入點方法(公共的切入點表達式@Pointcut("execution(*privatevoid}//前置通知切入點publicvoidbefore(JoinPointjoinPoint){("before...");}publicObjectaround(ProceedingJoinPointproceedingJoinPoint)throwsThrowable{("aroundbeforeObjectresult=("aroundafter...");returnresult;}publicvoidafter(JoinPointjoinPoint){("after...");}//返回后通知(程序在正常執(zhí)行的情況下,會執(zhí)行的后置通知)publicvoidafterReturning(JoinPointjoinPoint){("afterReturning}//異常通知(程序在出現(xiàn)異常的情況下,執(zhí)行的后置通知)publicvoidafterThrowing(JoinPointjoinPoint){("afterThrowing...");}}需要注意的是:當切入點方法使用private修飾時,僅能在當前切面類中該表達式,他切面類中也要當前類中的切入點表達式,就需要把prvate改為pulic,而在的時候,具體的語法為:1123456789publicclassMyAspect2publicvoidbefore(){("MyAspect2->before}}當在項目開發(fā)當中,我們定義了多個切面類,而多個切面類中多個切入點都匹配到了同一個目標方法。此時當目標方法在運行的時候,這多個切面類當中的這些通知方法都會運行。 1123456789publicclassMyAspect2//@Before("execution(*com.itheima.service.*.*(..))")publicvoidbefore(){("MyAspect2->before}//@After("execution(*com.itheima.service.*.*(..))")publicvoidafter(){("MyAspect2->after}}12123456789publicclassMyAspect3//@Before("execution(*com.itheima.service.*.*(..))")publicvoidbefore(){("MyAspect3->before}//@After("execution(*com.itheima.service.*.*(..))")publicvoidafter(){("MyAspect3-after}}123456789publicclassMyAspect4//@Before("execution(*com.itheima.service.*.*(..))")publicvoidbefore(){("MyAspect4->before}//@After("execution(*com.itheima.service.*.*(..))")publicvoidafter(){("MyAspect4->after}} 目標方法前方法:字母靠前的先執(zhí)行1234越后執(zhí)行//切面類的執(zhí)行順序(前置通知:數(shù)字越小先執(zhí)行;后置通知:數(shù)字越小5publicclassMyAspect267@Before("execution(*8("MyAspect2->before}@After("execution(*("MyAspect2->after}}1231234越后執(zhí)行//切面類的執(zhí)行順序(前置通知:數(shù)字越小先執(zhí)行后置通知:數(shù)字越小56789publicclassMyAspect3//@Before("execution(*com.itheima.service.*.*(..))")publicvoidbefore(){("MyAspect3->before}//@After("execution(*("MyAspect3-after}}@Order(1//切面類的執(zhí)行順序(前置通知:數(shù)字越小先執(zhí)行后置通知:數(shù)字越小越后執(zhí)行)publicclassMyAspect467@Before("execution(*8("MyAspect4->before}@After("execution(*("MyAspect4->after}}從AOP的程序到現(xiàn)在,都在使用切入點表達式來描述切入點。下面我們就來詳細的介紹一下切入點表達式的具體寫法。@annotation(……) 修飾符?返回 包名.類名.?方法名(方法參數(shù))throws異常修飾符:可省略(比如public、protected)包名.類名:可省略throws異常:可省略(注意是方法上拋出的異常,不是實際拋出的異常) *:單個獨立的任意符號,可以通配任意返回值、包名、類名、方法名、任意類型的一個參數(shù),也可以通配包、類、方法名的一部分*返回值可以使用*號代替(任意返回值類型*號代替,代表任意包(一層包使用一個*使用***
) )使用*代替包名(一層包使用一個* execution(** execution(** execution(* execution(* execution(*根據(jù)業(yè)務(wù)需要,可以使用且(&&)、或(||)、非(!) execution(*com.itheima.service.DeptService.list(..))||execution(*com.itheima.service.DeptService.delete(..))所有業(yè)務(wù)方法名在命名時盡量規(guī)范,方便切入點表達式快速匹配。如:查詢類方法都是find開12123456789//publicclassDeptServiceImplimplementsDeptServicepublicList<Dept>findAllDept()//省略代碼}publicDeptfindDeptById(Integerid)//省略代碼}publicvoidupdateDeptById(Integerid)//省略代碼}publicvoid//省略代碼}//其他代碼dept)}//匹配DeptServiceImpl類中以findexecution(* execution(*在滿足業(yè)務(wù)需要的前提下,盡量縮小切入點的匹配范圍。如:包名匹配盡量不使用..,使用 execution(*已經(jīng)學習了exection切入點表達式的語法。那么如果我們要匹配多個無規(guī)則的方法,比如:)和delet()這兩個方法。這個時候我們基于excutin這種切入點表達式來描述就不是很方便了。而在之前我們是將兩個切入點表達式組合在了一起完成的需求,這個是比較繁瑣的。我們可以借助于另一種切入點表達式annottion來描述這一類的切入點,從而來簡化切入點表達式的書寫。自定義注解11234public@interfaceMyLog{}業(yè)務(wù)類1123456789publicclassDeptServiceImplimplements{privateDeptMapper@MyLog//自定義注解(表示:當前方法屬于目標方法)publicList<Dept>list(){List<Dept>deptList=////intnum=return} //自定義注解(表示:當前方法屬于目標方法publicvoiddelete(Integerid)//1.}publicvoidsave(Dept{}publicDeptgetById(Integer{return}publicvoidupdate(Dept{}}1123456789publicclassMyAspect6//針對list方法、delete//publicvoidbefore(){("MyAspect6->before}("MyAspect6->after}}annotation基于注解的方式來匹配切入點方法。這種方式雖然多一步操作,我們需要自定義一個注解,但是相對來比較靈活。我們需要匹配哪個方法,就在方法上加上對應(yīng)的注解就可以了講解完了切入點表達式之后,接下來我們再來講解最后一個部分連接點。我們前面在講解AOP念的時候,我們提到過什么是連接點,連接點可以簡單理解為可以被AOP控制的方法。我們目標對象當中所有的方法是不是都是可以被AOP控制的方法。而在SprinAOP在Spring中用JoinPint抽象了連接點,用它可以獲得方法執(zhí)行時的相關(guān)信息,如目標類名、方法名、方法參數(shù)等。對于其他四種通知,獲取連接點信息只能使用JoinPoint,它是ProcedingJoinPint1123456789publicclassMyAspect7privatevoid//publicvoidjoinPoint){(joinPoint.getSignature().getName()+"MyAspect7->before//publicvoidjoinPoint){(joinPoint.getSignature().getName()+"MyAspect7->after//publicObjectaround(ProceedingJoinPointpjp)throwsThrowable//獲取目標類名Stringnamepjp.getTarget().getClass().getName();//目標方法名StringmethodNamepjp.getSignature().getName();//Object[]args=("目標方法參數(shù):{}",//ObjectreturnValue=return}}SpingAOP的相關(guān)知識我們就已經(jīng)全部學習完畢了。最后我們要通過一個案例來對AOP應(yīng)用。就是當部門管理和員工管理當中的增、刪、改相關(guān)功能接口時,需要詳細的操作日志,并保存所記錄的日志信息包括當前接口的操作人是誰操作的,什么時間點操作的,以及的是哪個類當中的哪個方法,在這個方法的時候傳入進來的參數(shù)是什么,這個方法最終拿到的返回值是以上兩個問題的解決方案:可以使用AOP解決(每一個增刪改功能接口中要實現(xiàn)的記錄操作日志的邏輯代碼是相同)??梢园堰@部分記錄操作日志的通用的、重復(fù)性的邏輯代碼抽取出來定義在一個通知方法當中,我們可以把這部分記錄操作日志的通用的、重復(fù)性的邏輯代碼抽取出來定義在一個通知方法當中,我們通過AOP面向切面編程的方式,在不改動原始功能的基礎(chǔ)上來對原始的功能進行增強。目前我們所增強的功能就是來記錄操作日志,所以也可以使用AOP的技術(shù)來實現(xiàn)。使用AOP的技術(shù)來實現(xiàn)也是最為簡單,最為方便的。問題3:既然要基于AOP面向切面編程的方式來完成的功能,那么我們要使用AOP五種通知類型當中的 方法的運行時長,需要原始方法運行之前記錄開始時間,原始方法運行之后記錄結(jié)束時間。通過計算獲得方法的執(zhí)行耗時。要匹配業(yè)務(wù)接口當中所有的增刪改的方法,而增刪改方法在命名上沒有共同的前綴或后綴。此時如果使用execution切入點表達式也可以,但是會比較繁瑣。當遇到增刪改的方法名沒有規(guī)律時,就可以使用annotation<!--AOP<!--AOP起步依賴----createtableidintunsignedprimarykeyauto_incrementcommentoperate_userintunsignedcomment'操作人operate_timedatetimecomment'操作時間class_namevarchar(100)comment'操作的類名method_namevarchar(100)comme
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- T/CSWSL 018-2020奶牛用菌酶協(xié)同發(fā)酵飼料
- T/CRIA 29009-2023汽車輪胎徑向剛性、扭轉(zhuǎn)剛性和包絡(luò)剛性試驗方法
- T/CRIA 20003-2021長纖維色母粒用炭黑
- T/CRIA 18002-2019停車楔
- T/CRIA 16012-2022一般用途芳綸織物芯阻燃輸送帶
- T/CPMA 016-2020數(shù)字化預(yù)防接種門診基本功能標準
- T/CNFIA 165-2022大豆植物肉及其制品
- T/CIMA 0060-2023電能錄波器
- T/CHIA 26-2022兒童營養(yǎng)與健康管理信息系統(tǒng)技術(shù)規(guī)范
- T/CHES 69-2022抗旱需水分析技術(shù)導則
- 2024年版-生產(chǎn)作業(yè)指導書SOP模板
- 歷年考研英語一真題及答案
- 寵物殯葬師理論知識考試題庫50題
- 飛花令“水”的詩句100首含“水”字的詩句大全
- 門診常見眼科病
- 保育師中級培訓課件資源
- 心力衰竭病人的護理課件
- 教學機房規(guī)劃方案
- 腫瘤患者全程管理
- 可行性研究報告編制服務(wù)投標方案
- 大學生如何處理學習與娛樂的平衡
評論
0/150
提交評論