<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          自定義注解妙用,一行代碼搞定用戶操作日志記錄

          共 14877字,需瀏覽 30分鐘

           ·

          2022-04-01 20:43

          1.簡(jiǎn)介

          在使用spring完成項(xiàng)目的時(shí)候需要完成記錄日志,開(kāi)始以為Spring 的AOP功能,就可以輕松解決,半個(gè)小時(shí)都不用,可是經(jīng)過(guò)一番了解過(guò)后,發(fā)現(xiàn)一般的日志記錄,只能記錄一些簡(jiǎn)單的操作,例如表名、表名稱等記錄不到。

          這個(gè)時(shí)侯就用到了自定義注解,把想要記錄的內(nèi)容放在注解中,通過(guò)切入點(diǎn)來(lái)獲取到注解參數(shù),然后將參數(shù)插入數(shù)據(jù)庫(kù)記錄

          2.Spring AOP

          2.1.關(guān)于Spring AOP的一些術(shù)語(yǔ)

          • 切面(Aspect):在Spring AOP中,切面可以使用通用類或者在普通類中以@Aspect 注解(@AspectJ風(fēng)格)來(lái)實(shí)現(xiàn)
          • 連接點(diǎn)(Joinpoint):在Spring AOP中一個(gè)連接點(diǎn)代表一個(gè)方法的執(zhí)行
          • 通知(Advice):在切面的某個(gè)特定的連接點(diǎn)(Joinpoint)上執(zhí)行的動(dòng)作。通知有各種類型,其中包括"around"、"before”和"after"等通知。許多AOP框架,包括Spring,都是以攔截器做通知模型, 并維護(hù)一個(gè)以連接點(diǎn)為中心的攔截器鏈
          • 切入點(diǎn)(Pointcut):定義出一個(gè)或一組方法,當(dāng)執(zhí)行這些方法時(shí)可產(chǎn)生通知,Spring缺省使用AspectJ切入點(diǎn)語(yǔ)法。
          通知類型
          • 前置通知(@Before):在某連接點(diǎn)(join point)之前執(zhí)行的通知,但這個(gè)通知不能阻止連接點(diǎn)前的執(zhí)行(除非它拋出一個(gè)異常)
          • 返回后通知(@AfterReturning):在某連接點(diǎn)(join point)正常完成后執(zhí)行的通知:例如,一個(gè)方法沒(méi)有拋出任何異常,正常返回
          • 拋出異常后通知(@AfterThrowing):方法拋出異常退出時(shí)執(zhí)行的通知
          • 后通知(@After):當(dāng)某連接點(diǎn)退出的時(shí)候執(zhí)行的通知(不論是正常返回還是異常退出)
          • 環(huán)繞通知(@Around):包圍一個(gè)連接點(diǎn)(join point)的通知,如方法調(diào)用。這是最強(qiáng)大的一種通知類型,環(huán)繞通知可以在方法調(diào)用前后完成自定義的行為,它也會(huì)選擇是否繼續(xù)執(zhí)行連接點(diǎn)或直接返回它們自己的返回值或拋出異常來(lái)結(jié)束執(zhí)行。更多Java項(xiàng)目分享

          2.2.Spring AOP配置有兩種風(fēng)格:

          • XML風(fēng)格 = 采用聲明形式實(shí)現(xiàn)Spring AOP
          • AspectJ風(fēng)格 = 采用注解形式實(shí)現(xiàn)Spring AOP

          3.首先自定義注解

          定義一個(gè)日志描述和一個(gè)表名這里根據(jù)需要自定義注解

          package?com.ywj.log;
          ?
          import?java.lang.annotation.*;
          ?
          /**
          ?*?ClassName?Crmlog
          ?*?AOP日志記錄?自定義注解類
          ?*/

          @Target({ElementType.PARAMETER,?ElementType.METHOD})
          @Retention(RetentionPolicy.RUNTIME)
          @Documented
          public?@interface?SystemCrmlog?{
          ????/**
          ?????*?日志描述
          ?????*?對(duì)于什么表格進(jìn)行了什么操作
          ?????*/

          ????String?description()??default?"";
          ?
          ????/**
          ?????*?操作了的表名
          ?????*?@return
          ?????*/

          ????String??tableName()?default?"";
          }

          3.1.定義切面類,從切入點(diǎn)獲取注解信息保存到數(shù)據(jù)庫(kù)

          對(duì)于一些可能碰到的問(wèn)題我在方法的注釋里都有解決辦法,大家注意一下,這里我對(duì)于方法報(bào)錯(cuò)也有處理方法

          這里是對(duì)于切面類里使用到的兩個(gè)類解釋:

          AspectJ使用org.aspectj.lang.JoinPoint接口表示目標(biāo)類連接點(diǎn)對(duì)象,如果是環(huán)繞增強(qiáng)時(shí),使用org.aspectj.lang.ProceedingJoinPoint表示連接點(diǎn)對(duì)象,該類是JoinPoint的子接口。任何一個(gè)增強(qiáng)方法都可以通過(guò)將第一個(gè)入?yún)⒙暶鳛镴oinPoint訪問(wèn)到連接點(diǎn)上下文的信息。我們先來(lái)了解一下這兩個(gè)接口的主要方法:

          1)JoinPoint
          • java.lang.Object[] getArgs():獲取連接點(diǎn)方法運(yùn)行時(shí)的入?yún)⒘斜恚?/li>
          • Signature getSignature()?:獲取連接點(diǎn)的方法簽名對(duì)象;
          • java.lang.Object getTarget()?:獲取連接點(diǎn)所在的目標(biāo)對(duì)象;
          • java.lang.Object getThis()?:獲取代理對(duì)象本身;
          2)ProceedingJoinPoint

          ProceedingJoinPoint繼承JoinPoint子接口,它新增了兩個(gè)用于執(zhí)行連接點(diǎn)方法的方法:

          • java.lang.Object proceed() throws java.lang.Throwable:通過(guò)反射執(zhí)行目標(biāo)對(duì)象的連接點(diǎn)處的方法;
          • java.lang.Object proceed(java.lang.Object[] args) throws java.lang.Throwable:通過(guò)反射執(zhí)行目標(biāo)對(duì)象連接點(diǎn)處的方法,不過(guò)使用新的入?yún)⑻鎿Q原來(lái)的入?yún)ⅰ?a style="font-family:'Optima-Regular', Optima, 'PingFangSC-light', 'PingFangTC-light', 'PingFang SC', Cambria, Cochin, Georgia, Times, 'Times New Roman', serif;font-size:15px;text-align:left;background-color:rgb(255,255,255);">更多Java項(xiàng)目分享
          package?com.ywj.log;
          ?
          ?
          import?com.fasterxml.jackson.databind.ObjectMapper;
          import?com.ywj.log.biz.Sys_logBiz;
          import?com.ywj.log.dao.Sys_logDao;
          import?com.ywj.login.biz.Sys_UserBiz;
          import?com.ywj.login.dao.Sys_UserDao;
          import?com.ywj.login.dao.Sys_righDao;
          import?org.aspectj.lang.JoinPoint;
          import?org.aspectj.lang.annotation.*;
          import?org.springframework.stereotype.Component;
          import?org.springframework.web.context.request.RequestAttributes;
          import?org.springframework.web.context.request.RequestContextHolder;
          import?org.springframework.web.context.request.ServletRequestAttributes;
          ?
          import?javax.servlet.http.HttpServletRequest;
          import?java.lang.reflect.Method;
          import?java.text.SimpleDateFormat;
          import?java.util.Arrays;
          import?java.util.Date;
          import?java.util.List;
          import?java.util.Map;
          ?
          ?
          /**
          ?*?@ClassName?SystemLogAspect
          ?*?@Author?Administrator
          ?*?@Describe??定義切入面類
          ?*/

          @Aspect
          @Component
          public?class?SystemLogAspect?{
          ?
          ?
          ????/**
          ?????*?注解Pointcut切入點(diǎn)
          ?????*?定義出一個(gè)或一組方法,當(dāng)執(zhí)行這些方法時(shí)可產(chǎn)生通知
          ?????*?指向你的切面類方法
          ?????*?由于這里使用了自定義注解所以指向你的自定義注解
          ?????*/

          ????@Pointcut("@annotation(com.ywj.log.SystemCrmlog)")
          ????public?void?crmAspect()?{
          ????}
          ?
          ?
          ????/**
          ?????*拋出異常后通知(@AfterThrowing):方法拋出異常退出時(shí)執(zhí)行的通知
          ?????*?注意在這里不能使用ProceedingJoinPoint
          ?????*?不然會(huì)報(bào)錯(cuò)ProceedingJoinPoint?is?only?supported?for?around?advice
          ?????*?throwing注解為錯(cuò)誤信息
          ?????*?@param?joinPoint
          ?????*?@param?ex
          ?????*/

          ????@AfterThrowing(value="crmAspect()",?throwing="ex")
          ????public?void?afterThrowingMethod(JoinPoint?joinPoint,?Exception?ex)?throws?Exception?{
          ????????HttpServletRequest?httpServletRequest?=?getHttpServletRequest();
          ????????//獲取管理員用戶信息\
          ????????WebUtil?webUtil?=?new?WebUtil();
          ????????Map?user?=?webUtil.getUser(httpServletRequest);
          ????????CrmLogMessage?log=new?CrmLogMessage();
          ????????//獲取需要的信息
          ????????String?context=getServiceMthodDescription(joinPoint);
          ????????String?usr_name="";
          ????????String?rolename="";
          ????????if(user!=null){
          ????????????usr_name?=?user.get("usr_name").toString();
          ????????????rolename=user.get("rolename").toString();
          ????????}
          ????????//管理員姓名
          ????????log.setUserName(usr_name);
          ????????//角色名
          ????????log.setUserRole(rolename);
          ????????//日志信息
          ????????log.setContent(usr_name+context);
          ????????//設(shè)置參數(shù)集合
          ????????log.setRemarks(getServiceMthodParams(joinPoint));
          ????????//設(shè)置表名
          ????????log.setTableName(getServiceMthodTableName(joinPoint));
          ????????//操作時(shí)間
          ????????SimpleDateFormat?sif=new?SimpleDateFormat("yyyy-MM-dd?HH:mm:ss");
          ????????log.setDateTime(sif.format(new?Date()));
          ????????//設(shè)置ip地址
          ????????log.setIp(httpServletRequest.getRemoteAddr());
          ????????//設(shè)置請(qǐng)求地址
          ????????log.setRequestUrl(httpServletRequest.getRequestURI());
          ????????//執(zhí)行結(jié)果
          ????????log.setResult("執(zhí)行失敗");
          ????????//錯(cuò)誤信息
          ????????log.setExString(ex.getMessage());
          ????????//將數(shù)據(jù)保存到數(shù)據(jù)庫(kù)
          ????????Sys_logDao?sysLogDao=new?Sys_logDao();
          ????????sysLogDao.addSys_log(log);
          ????}
          ?
          ?
          ????/**
          ?????*?返回后通知(@AfterReturning):在某連接點(diǎn)(joinpoint)
          ?????*?正常完成后執(zhí)行的通知:例如,一個(gè)方法沒(méi)有拋出任何異常,正常返回
          ?????*?方法執(zhí)行完畢之后
          ?????*?注意在這里不能使用ProceedingJoinPoint
          ?????*?不然會(huì)報(bào)錯(cuò)ProceedingJoinPoint?is?only?supported?for?around?advice
          ?????*?crmAspect()指向需要控制的方法
          ?????*??returning??注解返回值
          ?????*?@param?joinPoint
          ?????*?@param?returnValue??返回值
          ?????*?@throws?Exception
          ?????*/

          ????@AfterReturning(value?=?"crmAspect()",returning?=?"returnValue")
          ????public??void?doCrmLog(JoinPoint?joinPoint,Object?returnValue)?throws?Exception?{
          ????????HttpServletRequest?httpServletRequest?=?getHttpServletRequest();
          ????????//獲取管理員用戶信息
          ????????WebUtil?webUtil?=?new?WebUtil();
          ????????Map?user?=?webUtil.getUser(httpServletRequest);
          ????????CrmLogMessage?log=new?CrmLogMessage();
          ????????String?context=getServiceMthodDescription(joinPoint);
          ?
          ????????String?usr_name="";
          ????????String?rolename="";
          ????????if(user!=null){
          ?????????usr_name?=?user.get("usr_name").toString();
          ?????????rolename=user.get("rolename").toString();
          ????????}
          ????????//管理員姓名
          ????????log.setUserName(usr_name);
          ????????//角色名
          ????????log.setUserRole(rolename);
          ????????//日志信息
          ????????log.setContent(usr_name+context);
          ????????//設(shè)置參數(shù)集合
          ????????log.setRemarks(getServiceMthodParams(joinPoint));
          ????????//設(shè)置表名
          ????????log.setTableName(getServiceMthodTableName(joinPoint));
          ????????//操作時(shí)間
          ????????SimpleDateFormat?sif=new?SimpleDateFormat("yyyy-MM-dd?HH:mm:ss");
          ????????log.setDateTime(sif.format(new?Date()));
          ????????//設(shè)置ip地址
          ????????log.setIp(httpServletRequest.getRemoteAddr());
          ????????//設(shè)置請(qǐng)求地址
          ????????log.setRequestUrl(httpServletRequest.getRequestURI());
          ????????if(returnValue!=null){
          ???????????if(returnValue?instanceof?List){
          ???????????????List?ls=?(List)?returnValue;
          ???????????????if(ls.size()>0){
          ???????????????????log.setResult("執(zhí)行成功");
          ???????????????}else{
          ???????????????????log.setResult("執(zhí)行成功");
          ???????????????}
          ???????????}else?if(returnValue?instanceof?Boolean){
          ???????????????Boolean?falg=?(Boolean)?returnValue;
          ???????????????if(falg){
          ???????????????????log.setResult("執(zhí)行成功");
          ???????????????}else{
          ???????????????????log.setResult("執(zhí)行失敗");
          ???????????????}
          ???????????}else?if(returnValue?instanceof?Integer){
          ???????????????Integer?i=?(Integer)?returnValue;
          ???????????????if(i>0){
          ???????????????????log.setResult("執(zhí)行成功");
          ???????????????}else{
          ???????????????????log.setResult("執(zhí)行失敗");
          ???????????????}
          ???????????}else{
          ???????????????log.setResult("執(zhí)行成功");
          ???????????}
          ?
          ????????}
          ????????//將數(shù)據(jù)保存到數(shù)據(jù)庫(kù)
          ????????Sys_logDao?sysLogDao=new?Sys_logDao();
          ????????sysLogDao.addSys_log(log);
          ????}
          ?
          ?
          ????/**
          ?????*獲取自定義注解里的日志描述
          ?????*?@param?joinPoint
          ?????*?@return?返回注解里面的日志描述
          ?????*?@throws?Exception
          ?????*/

          ????private?String?getServiceMthodDescription(JoinPoint?joinPoint)
          ????????????throws?Exception?
          {
          ????????//類名
          ????????String?targetName?=?joinPoint.getTarget().getClass().getName();
          ????????//方法名
          ????????String?methodName?=?joinPoint.getSignature().getName();
          ????????//參數(shù)
          ????????Object[]?arguments?=?joinPoint.getArgs();
          ????????//通過(guò)反射獲取示例對(duì)象
          ????????Class?targetClass?=?Class.forName(targetName);
          ????????//通過(guò)實(shí)例對(duì)象方法數(shù)組
          ????????Method[]?methods?=?targetClass.getMethods();
          ????????String?description?=?"";
          ????????for(Method?method?:?methods)?{
          ????????????//判斷方法名是不是一樣
          ????????????if(method.getName().equals(methodName))?{
          ????????????????//對(duì)比參數(shù)數(shù)組的長(zhǎng)度
          ????????????????Class[]?clazzs?=?method.getParameterTypes();
          ????????????????if(clazzs.length?==?arguments.length)?{
          ????????????????????//獲取注解里的日志信息
          ????????????????????description?=?method.getAnnotation(SystemCrmlog.class).description();
          ????????????????????break;
          ????????????????}
          ????????????}
          ????????}
          ????????return?description;
          ????}
          ?
          ????/**
          ?????*獲取自定義注解里的表名
          ?????*?@param?joinPoint
          ?????*?@return?返回注解里的表名字
          ?????*?@throws?Exception
          ?????*/

          ????private?String?getServiceMthodTableName(JoinPoint?joinPoint)
          ????????????throws?Exception?
          {
          ????????//類名
          ????????String?targetName?=?joinPoint.getTarget().getClass().getName();
          ????????//方法名
          ????????String?methodName?=?joinPoint.getSignature().getName();
          ????????//參數(shù)
          ????????Object[]?arguments?=?joinPoint.getArgs();
          ????????//通過(guò)反射獲取示例對(duì)象
          ????????Class?targetClass?=?Class.forName(targetName);
          ????????//通過(guò)實(shí)例對(duì)象方法數(shù)組
          ????????Method[]?methods?=?targetClass.getMethods();
          ????????//表名
          ????????String?tableName?=?"";
          ????????for?(Method?method?:?methods)?{
          ????????????//判斷方法名是不是一樣
          ????????????if?(method.getName().equals(methodName))?{
          ????????????????//對(duì)比參數(shù)數(shù)組的長(zhǎng)度
          ????????????????Class[]?clazzs?=?method.getParameterTypes();
          ????????????????if?(clazzs.length?==?arguments.length)?{
          ????????????????????//獲取注解里的表名
          ????????????????????tableName?=?method.getAnnotation(SystemCrmlog.class).tableName();
          ????????????????????break;
          ????????????????}
          ????????????}
          ????????}
          ????????return?tableName;
          ????}
          ?
          ????/**
          ?????*?獲取json格式的參數(shù)用于存儲(chǔ)到數(shù)據(jù)庫(kù)中
          ?????*?@param?joinPoint
          ?????*?@return
          ?????*?@throws?Exception
          ?????*/

          ????private?String?getServiceMthodParams(JoinPoint?joinPoint)
          ????????????throws?Exception?
          {
          ????????Object[]?arguments?=?joinPoint.getArgs();
          ????????ObjectMapper?om=new?ObjectMapper();
          ????????return?om.writeValueAsString(arguments);
          ????}
          ?
          ????/**
          ?????*?獲取當(dāng)前的request
          ?????*?這里如果報(bào)空指針異常是因?yàn)閱为?dú)使用spring獲取request
          ?????*?需要在配置文件里添加監(jiān)聽(tīng)
          ?????*?
          ?????*?
          ?????*?org.springframework.web.context.request.RequestContextListener
          ?????*?

          ?????*?

          ?????*?@return
          ?????*/

          ????public?HttpServletRequest?getHttpServletRequest(){
          ????????RequestAttributes?ra?=?RequestContextHolder.getRequestAttributes();
          ????????ServletRequestAttributes?sra?=?(ServletRequestAttributes)ra;
          ????????HttpServletRequest?request?=?sra.getRequest();
          ????????return?request;
          ????}
          ?
          }

          每個(gè)切面?zhèn)鬟f的數(shù)據(jù)的都不一樣,最終決定,獲取切面的所有參數(shù),轉(zhuǎn)成json字符串,保存到數(shù)據(jù)庫(kù)中。更多Java項(xiàng)目分享

          相關(guān)類:

          日志信息類

          package?com.ywj.log;
          ?
          /**
          ?*?@ClassName?CrmLogMessage
          ?*?@Author?Administrator
          ?*?@Describe?數(shù)據(jù)庫(kù)日志類
          ?*/

          public?class?CrmLogMessage?{
          ????private?Integer?logid;//日志id
          ????private?String?UserName;//管理員姓名
          ????private?String?UserRole;//管理員角色
          ????private?String?Content;//日志描述
          ????private?String?Remarks;//參數(shù)集合
          ????private?String?TableName;//表格名稱
          ????private?String?DateTime;//操作時(shí)間
          ????private?String?resultValue;//返回值
          ????private?String?ip;//ip地址
          ????private?String??requestUrl;//請(qǐng)求地址
          ????private?String?result;//操作結(jié)果
          ????private??String?ExString;//錯(cuò)誤信息
          ?
          ????public?CrmLogMessage()?{
          ????}
          ?
          ????@Override
          ????public?String?toString()?{
          ????????return?"CrmLogMessage{"?+
          ????????????????"logid="?+?logid?+
          ????????????????",?UserName='"?+?UserName?+?'\''?+
          ????????????????",?UserRole='"?+?UserRole?+?'\''?+
          ????????????????",?Content='"?+?Content?+?'\''?+
          ????????????????",?Remarks='"?+?Remarks?+?'\''?+
          ????????????????",?TableName='"?+?TableName?+?'\''?+
          ????????????????",?DateTime='"?+?DateTime?+?'\''?+
          ????????????????",?resultValue='"?+?resultValue?+?'\''?+
          ????????????????",?ip='"?+?ip?+?'\''?+
          ????????????????",?requestUrl='"?+?requestUrl?+?'\''?+
          ????????????????",?result='"?+?result?+?'\''?+
          ????????????????",?ExString='"?+?ExString?+?'\''?+
          ????????????????'}';
          ????}
          ?
          ????public?CrmLogMessage(Integer?logid,?String?userName,?String?userRole,?String?content,?String?remarks,?String?tableName,?String?dateTime,?String?resultValue,?String?ip,?String?requestUrl,?String?result,?String?exString)?{
          ????????this.logid?=?logid;
          ????????UserName?=?userName;
          ????????UserRole?=?userRole;
          ????????Content?=?content;
          ????????Remarks?=?remarks;
          ????????TableName?=?tableName;
          ????????DateTime?=?dateTime;
          ????????this.resultValue?=?resultValue;
          ????????this.ip?=?ip;
          ????????this.requestUrl?=?requestUrl;
          ????????this.result?=?result;
          ????????ExString?=?exString;
          ????}
          ?
          ????public?String?getExString()?{
          ????????return?ExString;
          ????}
          ?
          ????public?void?setExString(String?exString)?{
          ????????ExString?=?exString;
          ????}
          ?
          ????public?Integer?getLogid()?{
          ????????return?logid;
          ????}
          ?
          ????public?void?setLogid(Integer?logid)?{
          ????????this.logid?=?logid;
          ????}
          ?
          ????public?String?getUserName()?{
          ????????return?UserName;
          ????}
          ?
          ????public?void?setUserName(String?userName)?{
          ????????UserName?=?userName;
          ????}
          ?
          ????public?String?getUserRole()?{
          ????????return?UserRole;
          ????}
          ?
          ????public?void?setUserRole(String?userRole)?{
          ????????UserRole?=?userRole;
          ????}
          ?
          ????public?String?getContent()?{
          ????????return?Content;
          ????}
          ?
          ????public?void?setContent(String?content)?{
          ????????Content?=?content;
          ????}
          ?
          ????public?String?getRemarks()?{
          ????????return?Remarks;
          ????}
          ?
          ????public?void?setRemarks(String?remarks)?{
          ????????Remarks?=?remarks;
          ????}
          ?
          ????public?String?getTableName()?{
          ????????return?TableName;
          ????}
          ?
          ????public?void?setTableName(String?tableName)?{
          ????????TableName?=?tableName;
          ????}
          ?
          ????public?String?getDateTime()?{
          ????????return?DateTime;
          ????}
          ?
          ????public?void?setDateTime(String?dateTime)?{
          ????????DateTime?=?dateTime;
          ????}
          ?
          ????public?String?getResultValue()?{
          ????????return?resultValue;
          ????}
          ?
          ????public?void?setResultValue(String?resultValue)?{
          ????????this.resultValue?=?resultValue;
          ????}
          ?
          ????public?String?getIp()?{
          ????????return?ip;
          ????}
          ?
          ????public?void?setIp(String?ip)?{
          ????????this.ip?=?ip;
          ????}
          ?
          ????public?String?getRequestUrl()?{
          ????????return?requestUrl;
          ????}
          ?
          ????public?void?setRequestUrl(String?requestUrl)?{
          ????????this.requestUrl?=?requestUrl;
          ????}
          ?
          ????public?String?getResult()?{
          ????????return?result;
          ????}
          ?
          ????public?void?setResult(String?result)?{
          ????????this.result?=?result;
          ????}
          }

          用來(lái)獲取登錄用戶信息的幫助類:

          package?com.ywj.log;
          ?
          import?com.base.web.BaseAction;
          ?
          import?javax.servlet.http.HttpServletRequest;
          import?java.util.Map;
          ?
          /**
          ?*?@ClassName?WebUtil
          ?*?@Author?Administrator
          ?*?@Describe??日志幫助類?用來(lái)獲取session中的用戶信息來(lái)存入數(shù)據(jù)庫(kù)
          ?*/

          public?class?WebUtil??{
          ?
          ?
          ????/**
          ?????*?從session中獲取到用戶對(duì)象
          ?????*?@return
          ?????*/

          ????public?Map???getUser(HttpServletRequest?request){
          ????????Map?attribute=null;
          ????????if(request!=null){
          ????????Object?user?=?request.getSession().getAttribute(Constans.USER_KEY);
          ??????attribute?=?(Map)?user;}
          ????return?attribute;
          }
          ????
          }

          在你的spring-context.xml中配置

          ??
          ????<aop:aspectj-autoproxy?proxy-target-class="true"?/>
          ????
          ?
          ????<context:component-scan?base-package="com.*.*.biz.impl"?/>

          然后在你需要記錄的方法上加上注解

          @SystemCrmlog(description?=?"進(jìn)行了登錄操作",tableName?=Constans.USER_TABLENAME)

          效果這里表名使用了常量類

          ce52871d0ea550436ab17774d0efca9e.webp

          對(duì)于一些表的信息可以寫一個(gè)常量類

          93b7dabb51db961ffaab5d53f1c785fd.webp

          然后執(zhí)行登錄操作數(shù)據(jù)庫(kù)記錄為:

          7ab221c2196b11f454ed67f3eb2e8419.webp

          來(lái)源:blog.csdn.net/yjt520557/article/details/85099115


          bd8baf775eaa92d85d16de703b886614.webp


          程序汪資料鏈接

          程序汪接的7個(gè)私活都在這里,經(jīng)驗(yàn)整理

          Java項(xiàng)目分享 最新整理全集,找項(xiàng)目不累啦 06版

          堪稱神級(jí)的Spring Boot手冊(cè),從基礎(chǔ)入門到實(shí)戰(zhàn)進(jìn)階

          臥槽!字節(jié)跳動(dòng)《算法中文手冊(cè)》火了,完整版 PDF 開(kāi)放下載!

          臥槽!阿里大佬總結(jié)的《圖解Java》火了,完整版PDF開(kāi)放下載!

          字節(jié)跳動(dòng)總結(jié)的設(shè)計(jì)模式 PDF 火了,完整版開(kāi)放下載!


          歡迎添加程序汪個(gè)人微信 itwang009? 進(jìn)粉絲群或圍觀朋友圈

          瀏覽 23
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  小视频一区 | 性视频在线 | 青草视频在线观看视频 | 91网站九色 | 熟女乱伦图片 |