Spring AOP從入門到放棄之自定義註解收集系統日誌

但願的效果爲

需求

用戶點擊了某個界面,請求了後臺某個接口。接口請求到後臺後,記錄請求的數據到數據庫中。html

實現方式

一、自定義一個註解,被加註解的方法,請求的數據被保存下來 二、定義一個aop 去攔截被註解的方法 三、寫一個線程池、執行攔截後的邏輯。也就是保存到數據庫中java

效果圖

這裏寫圖片描述

查看到剛剛請求用戶列表界面的執行狀況git

這裏寫圖片描述

實現步驟

一、自定義註解

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SLog {
	String value() default "";
}

定義一個aop攔截註解

@Aspect
@Component
public class SLogAspect {

    /**
     * 保存日誌到數據庫的線程池
     */
    ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat("SLogAspect-Thread-%d").build();

    ExecutorService executor = new ThreadPoolExecutor(5,200,0L, TimeUnit.MILLISECONDS,
            new LinkedBlockingQueue<Runnable>(1024),
            threadFactory,
            new ThreadPoolExecutor.AbortPolicy());


    @Pointcut("@annotation(com.slife.annotation.SLog)")
    public void logPointCut() {
    }

    @Around("logPointCut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        long beginTime = System.currentTimeMillis();
        // 執行方法
        Object result = point.proceed();
        // 執行時長(毫秒)
        long time = System.currentTimeMillis() - beginTime;

        // 獲取request
        HttpServletRequest request = ServletUtils.getHttpServletRequest();
        //獲取請求的ip
        String ip = IPUtils.getIpAddr(request);
        SaveLogTask saveLogTask = new SaveLogTask(point, time, ip);
        //保存日誌到數據庫
        executor.execute(saveLogTask);

        return result;
    }


}

線程池執行保存數據到數據庫

/**
 *
 * @author chen
 * @date 2017/9/19
 * <p>
 * Email 122741482@qq.com
 * <p>
 * Describe:
 */
public class SaveLogTask implements Runnable {


    private SlifeLogDao slifeLogDao = ApplicationContextRegister.getBean(SlifeLogDao.class);

    private ProceedingJoinPoint joinPoint;
    private long time;
    private String ip;

    public SaveLogTask(ProceedingJoinPoint point, long time, String ip) {
        this.joinPoint = point;
        this.time = time;
        this.ip = ip;
    }

    @Override
    public void run() {
        saveLog(joinPoint, time, ip);
    }

    /**
     * 保存日誌 到數據庫
     *
     * @param joinPoint
     * @param time
     */
    private void saveLog(ProceedingJoinPoint joinPoint, long time, String ip) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();

        SlifeLog slifeLog = new SlifeLog();
        SLog sLog = method.getAnnotation(SLog.class);

        if (slifeLog != null) {
            // 註解上的描述
            slifeLog.setMsg(sLog.value());
        }
        // 請求的方法名
        String className = joinPoint.getTarget().getClass().getName();
        String methodName = signature.getName();
        slifeLog.setSrc(className + "." + methodName + "()");

        // 請求的參數
        Object[] args = joinPoint.getArgs();
        try {
            String params = JSON.toJSONString(args[0]);
            slifeLog.setParams(params);
        } catch (Exception e) {

        }

        // 設置IP地址
        slifeLog.setIp(ip);
        // 用戶名
        ShiroUser currUser = SlifeSysUser.ShiroUser();

        if (null == currUser) {
            if (null != slifeLog.getParams()) {
                slifeLog.setName(slifeLog.getParams());
                slifeLog.setLoginName(slifeLog.getParams());
            } else {
                slifeLog.setName("獲取用戶信息爲空");
                slifeLog.setLoginName("獲取用戶信息爲空");
                slifeLog.setCreateId(-1L);
            }
        } else {
            slifeLog.setName(currUser.getName());
            slifeLog.setLoginName(currUser.getUsername());

        }

        slifeLog.setUseTime(time);

        // 保存系統日誌
        slifeLogDao.insert(slifeLog);
    }
}

給須要的方法加註解

@SLog("獲取用戶列表數據")
    @ApiOperation(value = "獲取用戶列表數據", notes = "獲取用戶列表:使用約定的DataTable")
    @PostMapping(value = "/list")
    @ResponseBody
    public DataTable<SysUser> list(@RequestBody DataTable dt, ServletRequest request) {
        return sysUserService.pageSearch(dt);
    }




  @SLog("獲取用戶列表數據")

簡單的一個 記錄請求的日誌 實現。github

說明

這裏把保存到數據庫的邏輯寫到了一個線程池中,主要是不但願記錄日誌的邏輯影響了用戶請求數據接口的邏輯,和性能。數據庫

點擊獲取阿里雲優惠券

個人官網 個人博客app

個人官網http://guan2ye.com 個人CSDN地址http://blog.csdn.net/chenjianandiyi 個人簡書地址http://www.jianshu.com/u/9b5d1921ce34 個人githubhttps://github.com/javanan 個人碼雲地址https://gitee.com/jamen/ 阿里雲優惠券https://promotion.aliyun.com/ntms/act/ambassador/sharetouser.html?userCode=vf2b5zld&utm_source=vf2b5zldide

相關文章
相關標籤/搜索