Spring框架基于AOP實(shí)現(xiàn)簡單日志管理步驟解析
SPringAOP的使用
技術(shù)概述,描述這個(gè)技術(shù)是做什么?學(xué)習(xí)該技術(shù)的原因,技術(shù)的難點(diǎn)在哪里。
為了實(shí)現(xiàn)項(xiàng)目管理員端的操作數(shù)據(jù)庫日志,便于方便所以利用Spring框架的AOP機(jī)制進(jìn)行實(shí)現(xiàn),項(xiàng)目的難點(diǎn)在于如果設(shè)置切入點(diǎn),如何獲取參數(shù)。
技術(shù)詳述,描述你是如何實(shí)現(xiàn)和使用該技術(shù)的,要求配合代碼和流程圖詳細(xì)描述??梢栽偌?xì)分多個(gè)點(diǎn),分開描述各個(gè)部分。
在applicationContext.xml中開啟AOP代理
<aop:aspectj-autoproxy />
自定義一個(gè)注解
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface LogAnno { String operatorType(); }
編寫一個(gè)切面類
@Component @Aspect public class LogAopAspect { @Autowired LogtableService logtableService;//Logtable為數(shù)據(jù)庫中的一張表,用于存儲日志信息 @Around("@annotation(qj.admin.aspect.LogAnno)")//設(shè)定需要捕獲的標(biāo)簽 public Object around(ProceedingJoinPoint pjp) throws Throwable { MethodSignature methodSignature =(MethodSignature)pjp.getSignature(); Method method = methodSignature.getMethod(); String targetName = pjp.getTarget().getClass().getName(); System.out.println("增強(qiáng)的類是:"+targetName); System.out.println("增強(qiáng)的方法是:"+method.getName()); Method realMethod = pjp.getTarget().getClass().getDeclaredMethod(methodSignature.getName(), method.getParameterTypes()); LogAnno logAnno = realMethod.getAnnotation(LogAnno.class);//獲取注解的方法上的自定義標(biāo)簽類 String operatortype = logAnno.operatorType();//獲取到自定義標(biāo)簽上的注解如“修改賬戶狀態(tài)” //String operatortype = "修改用戶積分"; AdminLog adminLog = new AdminLog(); adminLog.setOperatortype(operatortype); adminLog.setOperator("123"); Object resultObject = null; Object [] parameter = pjp.getArgs();//獲取注解的方法的傳入?yún)?shù) try { resultObject = pjp.proceed(); adminLog.setOperatorresult("正常 "+Arrays.toString(parameter)); } catch (Exception e) { // TODO: handle exception adminLog.setOperatorresult("失敗"); } finally { adminLog.setOperatordate(new Date()); logtableService.addLog(adminLog); } return resultObject; }
用自定義注解注解一個(gè)方法
@LogAnno(operatorType = "修改賬戶狀態(tài)") public void handleUser(int IDNumber, int type) { User user = userDAO.get(IDNumber); userDAO.update(user, type); }
項(xiàng)目目錄結(jié)構(gòu)
技術(shù)使用中遇到的問題和解決過程。要求問題的描述和解決有一定的內(nèi)容,不能草草概括。要讓遇到相關(guān)問題的人看了你的博客之后能夠解決該問題。
剛剛開始的時(shí)候時(shí)候僅僅利用Method method = methodSignature.getMethod();來獲取當(dāng)前增強(qiáng)的方法,但是在接下來的LogAnno logAnno = method.getAnnotation(LogAnno.class);中g(shù)et到的logAnno類為空,而上面通過打印System.out.println("增強(qiáng)的方法是:"+method.getName());顯示增加的方法并沒有錯(cuò)誤,導(dǎo)致這就陷入了我的知識盲區(qū),經(jīng)過查找資料,大部分教程都說在自定義注解類中添加@Retention(RetentionPolicy.RUNTIME)即可解決問題,但是我添加之后還是同樣的問題,最后意識到,可能這方法所獲取的函數(shù)是兩個(gè)不同的函數(shù),最后又經(jīng)過查找最終發(fā)現(xiàn)原來是這個(gè)aop攔截的是ServiceImpl的一個(gè)方法,然后這個(gè)ServiceImpl又啟動(dòng)了事務(wù)管理,而事務(wù)管理又是基于AOP的。
也就是說,這個(gè)權(quán)限的@Around的切面攔截的是個(gè)代理對象的方法,而代理對象的方法是不會把原來父類中的方法的注解加上去的,所以這里這個(gè)注解的對象為null。
最后運(yùn)用Method realMethod = pjp.getTarget().getClass().getDeclaredMethod(methodSignature.getName(), method.getParameterTypes());獲取到了真正需要的增強(qiáng)的函數(shù)。
總結(jié)
利用Spring的AOP機(jī)制確實(shí)能夠大大減少代碼量,很容易的就實(shí)現(xiàn)了日志的管理
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章

Java使用bcrypt實(shí)現(xiàn)對密碼加密效果詳解

Python實(shí)現(xiàn)filter函數(shù)實(shí)現(xiàn)字符串切分