AOP實(shí)現(xiàn)日志記錄

概述:

????????在開發(fā)中我們需要將用戶的訪問(wèn)記錄當(dāng)作日志寫入數(shù)據(jù)庫(kù)中,如果給每個(gè)Controller層方法都加上相同的記錄日志的代碼,這樣無(wú)疑會(huì)造成代碼的冗余,也不利于程序的擴(kuò)展,所以我們可以通過(guò)aop編程,利用橫切技術(shù),動(dòng)態(tài)給每個(gè)方法添加記錄日志功能;

步驟:

1)陋葡、開啟aop注解支持;

? ??<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

2)欧聘、編寫切面類;

? ??在切面類上添加@Component(將切面類添加到IOC容器)渺蒿、@Aspect(聲明該類為切面類)

3)仅醇、編寫環(huán)繞通知;

? ??在環(huán)繞通知的方法上加入@Around注解;

代碼展示:

@Around("execution(* com.itheima.controller.*.*(..))")

public Object around(ProceedingJoinPoint pjp){

? ? Object obj = null;

? ? try {

? ? ? ? //得到訪問(wèn)時(shí)間

? ? ? ? Date visitTime = new Date();

? ? ? ? //獲取到目標(biāo)對(duì)象的字節(jié)碼對(duì)象

? ? ? ? Class clazz = pjp.getTarget().getClass();

? ? ? ? //得到當(dāng)前目標(biāo)對(duì)象中方法的參數(shù)

? ? ? ? Object[] args = pjp.getArgs();

? ? ? ? //放行方法

? ? ? ? obj = pjp.proceed(args);

? ? ? ? if(!pjp.getSignature().getName().equals("ininBinder")){

? ? ? ? ? ? //得到一個(gè)日志對(duì)象

? ? ? ? ? ? SysLog log = new SysLog();

? ? ? ? ? ? //通過(guò)目標(biāo)字節(jié)碼對(duì)象獲取該對(duì)象的類名以及被代理方法的方法名;

? ? ? ? ? ? log.setMethod("類名為:"+clazz.getName()+"方法名為:"+pjp.getSignature().getName());//"類名為:"+XXX+"方法名為:"+XXX

? ? ? ? ? ? log.setExecutionTime(new Date().getTime()-visitTime.getTime());

? ? ? ? ? ? log.setIp(request.getRemoteAddr());//通過(guò)request域?qū)ο螳@取IP;

? ? ? ? ? ? log.setUrl(request.getRequestURI());//通過(guò)request域?qū)ο螳@取URI

? ? ? ? ? ? log.setUsername(request.getRemoteUser());//通過(guò)request域?qū)ο螳@取登錄的用戶名

? ? ? ? ? ? log.setVisitTime(visitTime);

? ? ? ? ? ? //日志入庫(kù)

? ? ? ? ? ? logService.save(log);

? ? ? ? }

? ? }catch (Throwable t){

? ? ? ? //還原異常(使用AOP編程時(shí)一定要注意還原異常,否則權(quán)限不足時(shí)會(huì)出現(xiàn)404)

? ? ? ? if(t.getMessage().equals("Access is denied")){

? ? ? ? ? ? throw new AccessDeniedException("權(quán)限不足沿后!");

? ? ? ? }else {

? ? ? ? ? ? try {

? ? ? ? ? ? ? ? throw new Exception("權(quán)限不足期升!");

? ? ? ? ? ? } catch (Exception e) {

? ? ? ? ? ? ? ? e.printStackTrace();

? ? ? ? ? ? }

? ? ? ? }

? ? ? ? t.printStackTrace();

? ? }

? ? return obj;//返回被代理方法的返回值;

}

4)、在配置文件中添加掃描切面類所在的包;

????<context:component-scan base-package="切面類所在的包名"/>

說(shuō)明:

? ??在步驟三中需要用到request域?qū)ο?所以在切面類中注入request域?qū)ο?注入request域?qū)ο笄疤崾荌OC容器中擁有request域?qū)ο?我們可以通過(guò)在web.xml文件中添加一個(gè)監(jiān)聽器,用來(lái)監(jiān)聽request域?qū)ο蟮膭?chuàng)建,request域?qū)ο髣?chuàng)建完成后自動(dòng)放入IOC容器;

????代碼實(shí)現(xiàn):

????? <listener>

? ? ? ? <!--監(jiān)聽request對(duì)象的創(chuàng)建,request創(chuàng)建完成后將其放入ioc容器-->

<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>

????</listener>

關(guān)注點(diǎn):

????1)烙样、代碼冗余時(shí)使用AOP編程;(例:事務(wù)、日志......)

????2)蕊肥、在封裝日志對(duì)象時(shí),有幾個(gè)參數(shù)需要通過(guò)request域?qū)ο螳@取比較方便;(例:ip谒获、url、username)

????????????????獲取ip:request.getRemoteAddr()壁却;

????????????????獲取url:request.getRequestURL()批狱;

????????????????獲取username:request.getRemoteUser();

? ? ? ? ? ? 說(shuō)明:如果不使用request域?qū)ο螳@取,也可以使用反射方法式(比較麻煩);

????3)展东、獲取請(qǐng)求所訪問(wèn)的類名+方法名:

????????????????如果我們想要在通知中獲取目標(biāo)對(duì)象的類名以及當(dāng)前被增強(qiáng)方法的方法名,我們通過(guò)反射即可實(shí)現(xiàn)赔硫;

????????????1)、通過(guò)ProceedingJoinPoint對(duì)象即可獲取目標(biāo)對(duì)象的字節(jié)碼;

? ? ????????????????代碼:ProceedingJoinPoint.getTarget().getClass();

????????????2)盐肃、通過(guò)ProceedingJoinPoint對(duì)象也可獲取當(dāng)前被增強(qiáng)方法的方法名爪膊;

? ????????????????? 代碼:ProceedingJoinPoint.getSignature().getName();

? ? 4)、由于我們需要用到request域?qū)ο笏晕覀冃枰O(jiān)聽request域?qū)ο蟮膭?chuàng)建;

????????????<listener>

????????????????????<!--監(jiān)聽request對(duì)象的創(chuàng)建,request創(chuàng)建完成后將其放入ioc容器-->

<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>

????????????</listener>

? ? 5)恼蓬、使用aop編程一定要還原異常惊完;(即原來(lái)什么異常捕獲后再將該異常拋出)僵芹;

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末处硬,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子拇派,更是在濱河造成了極大的恐慌荷辕,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,627評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件件豌,死亡現(xiàn)場(chǎng)離奇詭異疮方,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)茧彤,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,180評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門骡显,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人曾掂,你說(shuō)我怎么就攤上這事惫谤。” “怎么了珠洗?”我有些...
    開封第一講書人閱讀 169,346評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵溜歪,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我许蓖,道長(zhǎng)蝴猪,這世上最難降的妖魔是什么调衰? 我笑而不...
    開封第一講書人閱讀 60,097評(píng)論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮自阱,結(jié)果婚禮上嚎莉,老公的妹妹穿的比我還像新娘。我一直安慰自己沛豌,他們只是感情好萝喘,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,100評(píng)論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著琼懊,像睡著了一般阁簸。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上哼丈,一...
    開封第一講書人閱讀 52,696評(píng)論 1 312
  • 那天启妹,我揣著相機(jī)與錄音,去河邊找鬼醉旦。 笑死饶米,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的车胡。 我是一名探鬼主播檬输,決...
    沈念sama閱讀 41,165評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼匈棘!你這毒婦竟也來(lái)了丧慈?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,108評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤主卫,失蹤者是張志新(化名)和其女友劉穎逃默,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體簇搅,經(jīng)...
    沈念sama閱讀 46,646評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡完域,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,709評(píng)論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了瘩将。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片吟税。...
    茶點(diǎn)故事閱讀 40,861評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖姿现,靈堂內(nèi)的尸體忽然破棺而出肠仪,到底是詐尸還是另有隱情,我是刑警寧澤建钥,帶...
    沈念sama閱讀 36,527評(píng)論 5 351
  • 正文 年R本政府宣布藤韵,位于F島的核電站,受9級(jí)特大地震影響熊经,放射性物質(zhì)發(fā)生泄漏泽艘。R本人自食惡果不足惜欲险,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,196評(píng)論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望匹涮。 院中可真熱鬧天试,春花似錦、人聲如沸然低。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,698評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)雳攘。三九已至带兜,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間吨灭,已是汗流浹背刚照。 一陣腳步聲響...
    開封第一講書人閱讀 33,804評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留喧兄,地道東北人无畔。 一個(gè)月前我還...
    沈念sama閱讀 49,287評(píng)論 3 379
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像吠冤,于是被迫代替她去往敵國(guó)和親浑彰。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,860評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容