国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發(fā)設(shè)計 > 正文

Spring注解實現(xiàn)日志記錄

2019-11-10 18:04:11
字體:
供稿:網(wǎng)友

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

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

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

現(xiàn)在實現(xiàn)一個通過注解方式實現(xiàn)的樣例:

一:準備

xml中需要開啟CGLIB動態(tài)代理

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

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: 保存系統(tǒng)日志注解接口 * * @author suoww * @date 2017-2-8 * */@Retention(RetentionPolicy.RUNTIME)  //注解會在class中存在,運行時可通過反射獲取@Target(ElementType.METHOD) //注解到方法public @interface SaveSysLog {    //調(diào)用方      1:嗨賺客戶端   2:支付寶   3:微信       4:錢寶     5:其他第三方    int send() default 1;         //接口url(從二級目錄記起)    String url();        //接口類型(前臺,后臺)    int type();}定義三個成員,這里只能定義八種基本數(shù)據(jù)類型,分別是

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: 切面類記錄接口調(diào)用失敗日志信息 * * @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,此方法需要為空,只是標識切點和切面關(guān)系     *     * @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{        //獲取反射參數(shù)        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();        //入?yún)ey        String[] parameterNames = ms.getParameterNames();        //入?yún)alue        Object[] arguments = joinPoint.getArgs();        Method method = ms.getMethod();        //方法的注解對象        SaveSysLog logParam = method.getAnnotation(SaveSysLog.class);          /* logger.debug("SaveSysLog注解參數(shù)send:" + logParam.send());          logger.debug("SaveSysLog注解參數(shù)url:" + logParam.url());         logger.debug("SaveSysLog注解參數(shù)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));*/                //拼參數(shù)        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());        //入?yún)⒆址?       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結(jié)束--------------");    }        /**     *      * Description: 異步記錄接口調(diào)用失敗的日志     *     * @param systemLog     * @author suoww     * @date 2017-2-8     */    @Async    public void handleLog(PartnerSystemLog sysLog){        //寫日志        int row = partnerSystemLogMapper.insertSelective(sysLog);        logger.debug("------日志寫入行數(shù):" + row);    }         /**     *      * Description: 對象轉(zhuǎn)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 表示切點后增強,即切入點的方法執(zhí)行結(jié)束后,即執(zhí)行切面中的增強代碼,但是不會改變原切入點方法返回值。下面具體說明

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

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

3.下面的是反射獲取的參數(shù),類名,方法名,入?yún)ey,參數(shù)value,注解對象,方法返回值

四:調(diào)用

controller中調(diào)用

 /**     *      * 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("根據(jù)channelId:" + channelId + "獲取到的商品集合為" + JSONObject.toJSONString(list));            return AjaxResult.success(list, "成功獲取頻道下商品");        }catch(ResultCodeException e){            e.printStackTrace();            return AjaxResult.failed("校驗失敗:" + e.getMessage());        }catch(Exception e){            e.printStackTrace();            return AjaxResult.failed("系統(tǒng)異常:" + e.getMessage());        }    }@SaveSysLog(send=InterfaceTypeConst.SendType.HZ, url="/goods/api/queryGoodsUnderChannel.html", type=InterfaceTypeConst.InterfaceType.APP)

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

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

五:測試

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

  入?yún)⒅衏hannelId=17

參數(shù)可以對應。

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


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 阜平县| 泊头市| 万载县| 莆田市| 司法| 太仆寺旗| 济阳县| 建瓯市| 瑞昌市| 靖边县| 文登市| 丰城市| 鞍山市| 遵义市| 宁城县| 庄河市| 聂荣县| 遂溪县| 志丹县| 涡阳县| 招远市| 尚志市| 宝坻区| 游戏| 容城县| 平潭县| 都安| 大城县| 射洪县| 澜沧| 游戏| 太仓市| 昭通市| 荔波县| 镇坪县| 泸水县| 西吉县| 措勤县| 新宾| 兖州市| 依安县|