亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

Spring注解實現日志記錄

2019-11-10 18:04:11
字體:
來源:轉載
供稿:網友

之前總結寫了一篇通過xml配置的方式,切面編程實現日志記錄的功能demo

http://blog.csdn.net/weiweiai123456/article/details/38561085

可參考http://blog.csdn.net/heirenheiren/article/details/36634497 ,講的是注解實現

現在實現一個通過注解方式實現的樣例:

一:準備

xml中需要開啟CGLIB動態代理

<!-- 啟用CGliB -->	<aop:aspectj-autoPRoxy proxy-target-class="true"/>切面編程----AOP,依賴的是代理,即JDK代理和CGLIB代理,而代理的實現依靠的是反射。

maven配置省...

二:注解類

SaveSysLog.java

package com.cooya.partner.metadata.entity.baseConfig;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;/** *  * Description: 保存系統日志注解接口 * * @author suoww * @date 2017-2-8 * */@Retention(RetentionPolicy.RUNTIME)  //注解會在class中存在,運行時可通過反射獲取@Target(ElementType.METHOD) //注解到方法public @interface SaveSysLog {    //調用方      1:嗨賺客戶端   2:支付寶   3:微信       4:錢寶     5:其他第三方    int send() default 1;         //接口url(從二級目錄記起)    String url();        //接口類型(前臺,后臺)    int type();}定義三個成員,這里只能定義八種基本數據類型,分別是

byte-->Byte

short-->Short

int-->Integer

long-->Long

float-->Float

double-->Double

char-->Character

boolean-->Boolean

注意:只能是上述這些8種類型的變量

三:切面類

SysLogAspect.java

package com.cooya.partner.service.baseConfig;import java.lang.reflect.Field;import java.lang.reflect.Method;import java.util.Date;import java.util.HashMap;import java.util.Map;import javax.annotation.Resource;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.Httpsession;import org.apache.shiro.SecurityUtils;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.annotation.AfterReturning;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Pointcut;import org.aspectj.lang.reflect.MethodSignature;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.scheduling.annotation.Async;import org.springframework.stereotype.Component;import org.springframework.web.context.request.RequestContextHolder;import org.springframework.web.context.request.ServletRequestAttributes;import com.alibaba.fastjson.JSONObject;import com.cooya.partner.constant.InterfaceTypeConst;import com.cooya.partner.metadata.entity.baseConfig.PartnerSystemLog;import com.cooya.partner.metadata.entity.baseConfig.SaveSysLog;import com.cooya.partner.metadata.entity.user.PartnerUser;import com.cooya.partner.metadata.mapper.baseConfig.PartnerSystemLogMapper;import com.cooya.partner.permission.dto.ShiroUser;/** *  * Description: 切面類記錄接口調用失敗日志信息 * * @author suoww * @date 2017-2-8 * */@Aspect@Componentpublic class SysLogAspect {        public static final int CODE_SUCCESS = 0;        private Logger logger = LoggerFactory.getLogger(SysLogAspect.class);        @Resource    private PartnerSystemLogMapper partnerSystemLogMapper;        /**     *      * Description: 定義切點名controllerAspect,此方法需要為空,只是標識切點和切面關系     *     * @author suoww     * @date 2017-2-8     */    @Pointcut("@annotation(com.cooya.partner.metadata.entity.baseConfig.SaveSysLog)")    public void controllerAspect(){}        /**     *      * Description:織入后增強      *     * @param join     * @author suoww     * @throws Exception      * @date 2017-2-8     */    @AfterReturning(pointcut = "controllerAspect()", returning = "res")    public void doAfter(JoinPoint joinPoint, Object res) throws Exception{        //獲取反射參數        logger.debug("---------------AfterReturning開始--------------");        if(null == res){            return;        }        Map<String, Object> map = Obj2Map(res);        int code = (Integer)map.get("code");        if(code == CODE_SUCCESS){            return;        }        String message = (String)map.get("message");        //類名        String targetName = joinPoint.getTarget().getClass().getSimpleName();        //得到方法名        String methodName = joinPoint.getSignature().getName();        MethodSignature ms = (MethodSignature) joinPoint.getSignature();        //入參key        String[] parameterNames = ms.getParameterNames();        //入參value        Object[] arguments = joinPoint.getArgs();        Method method = ms.getMethod();        //方法的注解對象        SaveSysLog logParam = method.getAnnotation(SaveSysLog.class);          /* logger.debug("SaveSysLog注解參數send:" + logParam.send());          logger.debug("SaveSysLog注解參數url:" + logParam.url());         logger.debug("SaveSysLog注解參數type:" + logParam.type());         logger.debug("targetName:" + targetName);        logger.debug("methodName:" + methodName);        logger.debug("ms:" + ms);        logger.debug("arguments:" + JSONObject.toJSONString(arguments));        logger.debug("parameterNames:" + JSONObject.toJSONString(parameterNames));        logger.debug("method:" + JSONObject.toJSONString(method));*/                //拼參數        PartnerSystemLog sysLog = new PartnerSystemLog();         //獲取用戶        if(logParam.type() == InterfaceTypeConst.InterfaceType.APP){            sysLog.setUserId(getAppUserId());        }else{            sysLog.setUserId(getMgrUserId());        }        sysLog.setSend(logParam.send());        sysLog.setUrl(logParam.url());        sysLog.setType(logParam.type());        //入參字符串        StringBuffer jsonParamSb = new StringBuffer();        for(int i = 0;i < parameterNames.length;i++){            jsonParamSb.append(parameterNames[i]).append("=").append(JSONObject.toJSONString(arguments[i]));            if(i != (parameterNames.length - 1)){                jsonParamSb.append("&");            }        }        //截取返回json        if(jsonParamSb.toString().length() <= 1000){            sysLog.setJsonParam(jsonParamSb.toString());        }else{            sysLog.setJsonParam(jsonParamSb.toString().substring(0, 1000));        }        //出參        sysLog.setJsonResult(JSONObject.toJSONString(res));        StringBuffer remarkSb = new StringBuffer();        remarkSb.append(targetName).append(".").append(methodName).append("報錯信息:").append(message);        //截取remark        if(remarkSb.toString().length() <= 1000){            sysLog.setRemark(remarkSb.toString());        }else{            sysLog.setRemark(remarkSb.toString().substring(0, 1000));         }        sysLog.setCreateTime(new Date());        sysLog.setUpdateTime(new Date());        handleLog(sysLog);        logger.debug("---------------AfterReturning結束--------------");    }        /**     *      * Description: 異步記錄接口調用失敗的日志     *     * @param systemLog     * @author suoww     * @date 2017-2-8     */    @Async    public void handleLog(PartnerSystemLog sysLog){        //寫日志        int row = partnerSystemLogMapper.insertSelective(sysLog);        logger.debug("------日志寫入行數:" + row);    }         /**     *      * Description: 對象轉map     *     * @param obj     * @return     * @throws Exception     * @author suoww     * @date 2017-2-8     */    public Map<String,Object> Obj2Map(Object obj) throws Exception{        Map<String,Object> map=new HashMap<String, Object>();        Field[] fields = obj.getClass().getDeclaredFields();        for(Field field:fields){            field.setaccessible(true);            map.put(field.getName(), field.get(obj));        }        return map;    }        /**     *      * Description: 獲取APP用戶ID     *     * @return     * @author suoww     * @date 2017-2-8     */    protected Long getAppUserId() {        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();        HttpSession session = request.getSession();        if (null == session) {            return null;        }        PartnerUser user = (PartnerUser) session.getAttribute("userInfo");        if (null == user) {            return null;        }        return user.getId();    }        /**     *      * Description: 獲取Mgr的用戶ID     *     * @return     * @author suoww     * @date 2017-2-8     */    protected Long getMgrUserId(){        ShiroUser user = (ShiroUser) SecurityUtils.getSubject().getPrincipal();        return user.getId();    }}

@Aspect和@Component分別表示這是一個切面類、Spring要幫我實例化對象并管理

@Pointcut(XX) :使用SaveSysLog作為注解(annotation)的將作為切點,對應切面controllerAspect

1.@AfterReturning 表示切點后增強,即切入點的方法執行結束后,即執行切面中的增強代碼,但是不會改變原切入點方法返回值。下面具體說明

2.pointcut="controllerAspect()" ,returning="res" 表示切點和切面對應關系,一個方法上可以有多個切面,指定順序

參考:http://blog.csdn.net/rainbow702/article/details/52185827

3.下面的是反射獲取的參數,類名,方法名,入參key,參數value,注解對象,方法返回值

四:調用

controller中調用

 /**     *      * Description: 接口:查詢場次下商品     *     * @param channelId     * @return     * @author suoww     * @date 2017-1-13     */    @RequestMapping("/queryGoodsUnderChannel")    @ResponseBody    @SaveSysLog(send=InterfaceTypeConst.SendType.HZ, url="/goods/api/queryGoodsUnderChannel.html", type=InterfaceTypeConst.InterfaceType.APP)    public AjaxResult queryGoodsUnderChannel(@RequestParam(value = "channelId", required = true)Long channelId){        try{            List<PartnerChannelGoodsDto> list = partnerGoods2ChannelService.getChannelGoodsDto(channelId);            logger.info("根據channelId:" + channelId + "獲取到的商品集合為" + JSONObject.toJSONString(list));            return AjaxResult.success(list, "成功獲取頻道下商品");        }catch(ResultCodeException e){            e.printStackTrace();            return AjaxResult.failed("校驗失?。?quot; + e.getMessage());        }catch(Exception e){            e.printStackTrace();            return AjaxResult.failed("系統異常:" + e.getMessage());        }    }@SaveSysLog(send=InterfaceTypeConst.SendType.HZ, url="/goods/api/queryGoodsUnderChannel.html", type=InterfaceTypeConst.InterfaceType.APP)

這里對應注解接口三個成員,send,url,type

queryGoodsUnderChannel 這個方法將整體作為一個切入點,結合@AfterReturning 在queryGoodsUnderChannel ()執行結束會,會進入到SysLogAspect.doAfter 執行一段代碼,記錄日志

五:測試

輸入http://localhost:8080/partner-app/goods/api/queryGoodsUnderChannel.html?channelId=17

  入參中channelId=17

參數可以對應。

總結:權限控制,日志記錄應該使用AOP,注解方式實際使用時候比XML配置方式要省事很多。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
精品国产精品三级精品av网址| 成人性生交大片免费观看嘿嘿视频| 日韩在线视频二区| 欧美大片免费观看| 麻豆国产精品va在线观看不卡| 中文字幕日韩免费视频| 国产精品吴梦梦| 国产精品美女www爽爽爽视频| 一本一本久久a久久精品综合小说| 成人久久精品视频| 国产免费观看久久黄| 日韩福利视频在线观看| 欧美黑人xxxx| 亚洲男人的天堂在线播放| 国产91九色视频| 91网站在线免费观看| 日本精品久久中文字幕佐佐木| 国产一区二区三区四区福利| 欧美成人免费va影院高清| 国产精品久久久av| 原创国产精品91| 欧美激情xxxx性bbbb| 夜夜躁日日躁狠狠久久88av| 久久久久在线观看| 91黑丝高跟在线| 日韩不卡在线观看| 国产精品久久久久影院日本| 久久久久久一区二区三区| 日韩精品欧美国产精品忘忧草| 国产精品一区二区性色av| 欧美剧在线观看| 国产91精品视频在线观看| 久操成人在线视频| 欧美在线观看一区二区三区| 日韩日本欧美亚洲| 日韩在线不卡视频| 亚洲国产精彩中文乱码av| 亚洲风情亚aⅴ在线发布| 亚洲精品乱码久久久久久按摩观| 国产香蕉97碰碰久久人人| 亚洲电影免费观看高清| 91成人国产在线观看| 91在线免费视频| 国产在线观看91精品一区| 亚洲图片在区色| 国产91色在线播放| 亚洲免费精彩视频| 在线播放国产一区中文字幕剧情欧美| 亚洲精品国产成人| 久久久久久尹人网香蕉| 亚洲一区二区三区乱码aⅴ蜜桃女| 亚洲国产精品yw在线观看| 欧美成人午夜激情在线| 黄色精品一区二区| 日韩精品在线免费播放| 久久婷婷国产麻豆91天堂| 国产欧美精品日韩| 98精品国产自产在线观看| 亚洲无限乱码一二三四麻| 国产精品成人一区二区| 色哟哟亚洲精品一区二区| 国产日韩在线看片| 欧美福利在线观看| 91久久精品美女高潮| 欧美日韩亚洲一区二区| 国产日韩换脸av一区在线观看| 成人免费大片黄在线播放| 色99之美女主播在线视频| 欧美国产精品日韩| 欧美野外猛男的大粗鳮| 欧美电影在线观看网站| 欧美日韩999| 国产精品aaaa| 久久精品夜夜夜夜夜久久| 久久精品91久久香蕉加勒比| 正在播放国产一区| 久久久精品一区二区| 成人黄色午夜影院| 国产精品视频成人| 国产精品一区二区久久国产| 日韩av一区在线观看| 国产亚洲在线播放| 国产亚洲欧洲高清| 日本最新高清不卡中文字幕| 美日韩丰满少妇在线观看| 欧美亚洲国产视频| 久久久久久久999精品视频| 欧美疯狂做受xxxx高潮| 久久久久久久久久久免费| 亚洲情综合五月天| 91精品国产乱码久久久久久蜜臀| 一本大道亚洲视频| 成人有码在线视频| 清纯唯美日韩制服另类| 亚洲色图偷窥自拍| 中文字幕日韩在线视频| 国产精品久久色| 久久久久久久爱| 精品福利樱桃av导航| 亚洲欧洲xxxx| 午夜精品三级视频福利| 亚洲精品在线观看www| 九九久久国产精品| 日韩av电影在线播放| 日韩在线观看成人| 精品国产一区二区三区四区在线观看| 伊人久久久久久久久久久| 2020国产精品视频| 国产精品成人一区二区三区吃奶| 久久99久久亚洲国产| 亚洲精品98久久久久久中文字幕| 国产亚洲人成a一在线v站| 欧美大片免费观看在线观看网站推荐| 亚洲精品日韩丝袜精品| 欧美尤物巨大精品爽| 亚洲在线观看视频网站| 亚洲成人黄色网址| 日韩**中文字幕毛片| 亚洲一区二区免费| 国外成人性视频| 欧美电影免费观看电视剧大全| 91亚洲精品视频| 国产精品人成电影在线观看| 亚洲欧洲av一区二区| 国产精品久久久一区| 91免费看片在线| 国产97在线亚洲| 亚洲成色999久久网站| 亚洲精品一区二区三区婷婷月| 日韩亚洲精品电影| 亚洲精品久久久久中文字幕二区| 亚洲精品国产精品国产自| 亚洲а∨天堂久久精品9966| 亚洲最大的成人网| 色樱桃影院亚洲精品影院| 国产一区二区三区日韩欧美| 欧美成人h版在线观看| 国产综合在线视频| 欧美专区中文字幕| 国产日韩欧美在线| 高清欧美性猛交xxxx黑人猛交| 欧美在线免费视频| 亚洲男人第一网站| 日韩精品欧美国产精品忘忧草| 久久99久久久久久久噜噜| 欧美色视频日本高清在线观看| 北条麻妃99精品青青久久| 日韩视频精品在线| 538国产精品视频一区二区| 超碰日本道色综合久久综合| 国产69久久精品成人看| 国产精品久久二区| 亚洲第一区在线观看| 久久天天躁夜夜躁狠狠躁2022| 精品无人区太爽高潮在线播放| 久久久国产精品x99av| 色老头一区二区三区| 国产精品视频一区二区高潮| 亚洲国产精品专区久久| 日韩欧美高清在线视频| 精品国产一区二区三区久久狼黑人| 国产丝袜一区二区三区免费视频| 亚洲人在线观看| 欧美第一淫aaasss性|