<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>

          自定義注解妙用,一行代碼搞定用戶操作日志記錄,你學(xué)會(huì)了嗎?

          共 14845字,需瀏覽 30分鐘

           ·

          2021-12-24 00:03

          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

          這里是為了方便大家理解如何實(shí)現(xiàn)給大家解釋一下

          2.1.關(guān)于Spring AOP的一些術(shù)語(yǔ)
          • 切面(Aspect):在Spring AOP中,切面可以使用通用類(lèi)或者在普通類(lèi)中以@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)作。通知有各種類(lèi)型,其中包括"around"、"before”和"after"等通知。許多AOP框架,包括Spring,都是以攔截器做通知模型, 并維護(hù)一個(gè)以連接點(diǎn)為中心的攔截器鏈
          • 切入點(diǎn)(Pointcut):定義出一個(gè)或一組方法,當(dāng)執(zhí)行這些方法時(shí)可產(chǎn)生通知,Spring缺省使用AspectJ切入點(diǎn)語(yǔ)法。
          通知類(lèi)型
          • 前置通知(@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)大的一種通知類(lèi)型,環(huán)繞通知可以在方法調(diào)用前后完成自定義的行為,它也會(huì)選擇是否繼續(xù)執(zhí)行連接點(diǎn)或直接返回它們自己的返回值或拋出異常來(lái)結(jié)束執(zhí)行
          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日志記錄?自定義注解類(lèi)
          ?*/

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

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

          ????String??tableName()?default?"";
          }
          3.1.定義切面類(lèi),從切入點(diǎn)獲取注解信息保存到數(shù)據(jù)庫(kù)

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

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

          AspectJ使用org.aspectj.lang.JoinPoint接口表示目標(biāo)類(lèi)連接點(diǎn)對(duì)象,如果是環(huán)繞增強(qiáng)時(shí),使用org.aspectj.lang.ProceedingJoinPoint表示連接點(diǎn)對(duì)象,該類(lèi)是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)⒘斜恚?/section>
          • 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)ⅰ?/section>
          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??定義切入面類(lèi)
          ?*/

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

          ????@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?
          {
          ????????//類(lèi)名
          ????????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?
          {
          ????????//類(lèi)名
          ????????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ù)中。

          相關(guān)類(lèi):

          日志信息類(lèi)

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

          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)獲取登錄用戶信息的幫助類(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)?用來(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中配置

          ??
          ????class="true"?/>
          ????
          ?
          ????package="com.ywj.log"?/>
          ???
          ????package="com.*.*.biz.impl"?/>

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

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

          效果這里表名使用了常量類(lèi)

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

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

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

          分享一下我寫(xiě)的《10萬(wàn)字Springboot經(jīng)典學(xué)習(xí)筆記》中,點(diǎn)擊下面小卡片,進(jìn)入【Java開(kāi)發(fā)寶典】,回復(fù):筆記,即可免費(fèi)獲取。

          點(diǎn)贊是最大的支持?
          瀏覽 70
          點(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>
                  丁香五月婷婷综合网 | 国产无卡无码在线观看视频 | 私人女仆扫地偷懒被主人颜色吃现在被喷尿洗脸 | 真实亲子乱一区二区 | 国产精品国产三级在线专区 |