需求:系统中经常需要记录员工的操作日志和用户的活动日志,简单的做法在每个需要的方法中进行日志保存操作,
但这样对业务代码入侵性太大,下面就结合AOP和自定义日志注解实现更方便的日志记录
 
首先看下一个简单的操作日志表
 
action_log
  • id
  • subject(日志主题)
  • content(日志内容)
  • create_by
  • create_time

日志主题可以用下面的枚举类来实现

package cn.bounter.common.model;

/**
* 应用日志主题枚举类
* @author simon
*
*/
public enum AppLogSubjectEnum { /** 客户 */
CUSTOMER(1,"客户"),
/** 商品 */
COMMODITY(2,"商品"),
/** 订单 */
ORDER(3,"订单"); private Integer value; private String name; private AppLogSubjectEnum(int value, String name) {
this.value = value;
this.name = name;
} public Integer getValue() {
return value;
} public String getName() {
return name;
} /**
* 自定义方法
* 根据枚举值获取枚举字符串内容
* @param value
* @return
*/
public static String stringOf(int value) {
for(AppLogSubjectEnum oneEnum : AppLogSubjectEnum.values()) {
if(oneEnum.value == value) {
return oneEnum.getName();
}
}
return null;
} }

然后让我们看下自定义注解

package cn.bounter.common.model;

import java.lang.annotation.*;

/**
* 应用日志注解
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface AppLog { /**
* 日志主题
* @return
*/
AppLogSubjectEnum subject(); /**
* 日志内容
* @return
*/
String content() default "";
}

接下来就是重头戏基于自定义注解的切面了

package cn.bounter.common.model;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
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.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import java.lang.reflect.Method;
import java.time.LocalDateTime; /**
* 应用日志切面
*/
@Aspect
@Component
public class AppLogAspect { @Autowired
private ActionLogService actionLogService; @Pointcut("@annotation(cn.bounter.common.model.AppLog)")
public void appLogPointCut() {
} @AfterReturning("appLogPointCut()")
public void addActionLog(JoinPoint joinPoint) {
Signature signature = joinPoint.getSignature();
MethodSignature methodSignature = (MethodSignature) signature;
Method method = methodSignature.getMethod(); //获取注解
AppLog appLog = method.getAnnotation(AppLog.class);
if (appLog == null) {
return;
} //保存数据库
actionLogService.save(
new ActionLog()
.setSubject(appLog.subject().getValue())
.setContent(appLog.content())
.setCreateBy(ShiroUtils.getUser()) //获取当前登录的用户
.setCreateTime(LocalDateTime.now())
);
} }

到这里就差不多,最后让我们看下怎么使用自定义日志注解

/**
* 新增订单
* @param order
* @return
*/
@AppLog(subject = AppLogSubjectEnum.ORDER, content = "新增")
public void save(Order order) {
orderService.save(order);
}

看完了之后是不是觉得挺简单哉!那就赶快自己动手试一试吧!

自定义日志注解 + AOP实现记录操作日志的更多相关文章

  1. 使用SpringBoot AOP 记录操作日志、异常日志

    平时我们在做项目时经常需要对一些重要功能操作记录日志,方便以后跟踪是谁在操作此功能:我们在操作某些功能时也有可能会发生异常,但是每次发生异常要定位原因我们都要到服务器去查询日志才能找到,而且也不能对发 ...

  2. spring-boot-route(十七)使用aop记录操作日志

    在上一章内容中--使用logback管理日志,我们详细讲述了如何将日志生成文件进行存储.但是在实际开发中,使用文件存储日志用来快速查询问题并不是最方便的,一个优秀系统除了日志文件还需要将操作日志进行持 ...

  3. Appfuse:记录操作日志

    appfuse的数据维护操作都发生在***form页面,与之对应的是***FormController,在Controller中处理数据的操作是onSubmit方法,既然所有的操作都通过onSubmi ...

  4. MVC 记录操作日志与过滤特殊字符

    最近进行的MVC系统需要用到记录操作日志和过滤特殊字符的功能,如果每个action中都调用记录日志的方法就太麻烦了,所以根据需要结合mvc的过滤机制 写了个特殊字符验证与记录操作日志的公用类: pub ...

  5. Tomcat会话超时时怎样记录操作日志,满足安全审计要求

    众所周知.在实际的Web应用程序中,会话管理一般都採用Web容器会话管理功能. 使用Tomcat做Webserver也是如此,并且从安全的角度考虑,尽量避免去更改和干预Web容器的会话管理功能. To ...

  6. Spring aop 记录操作日志 Aspect

    前几天做系统日志记录的功能,一个操作调一次记录方法,每次还得去收集参数等等,太尼玛烦了.在程序员的世界里,当你的一个功能重复出现多次,就应该想想肯定有更简单的实现方法.于是果断搜索各种资料,终于搞定了 ...

  7. springmvc集成aop记录操作日志

    首先说明一下,这篇文章只做了记录日志相关事宜 具体springmvc如何集成配置aop对cotroller进行拦截,请看作者的另一篇文章 http://www.cnblogs.com/guokai87 ...

  8. SpringBoot-AOP记录操作日志

    package com.meeno.inner.oa.extend.operaterecord.aop; import com.alibaba.fastjson.JSONArray; import c ...

  9. Django记录操作日志、LogEntry的使用

    LogEntry是在后台开发中经常用到的模块,它在admin是默认开启的. 可以使用LogEntry模块记录所有用户的操作记录.一方面可以用来监督,另一方面可以用来做回滚. 1. 使用LogEntry ...

随机推荐

  1. an ordered dict within the ordered dict

    w http://stackoverflow.com/questions/20166749/how-to-convert-an-ordereddict-into-a-regular-dict-in-p ...

  2. activiti 流程发起人控制

    最近做activiti流程发起人的控制,最开始的想法是新建一张表 ,通过控制流程定义id与发起人id进行控制,如果这样每次发布新的流程就必须 重新设置流程发起人,因为通过流程定义不能获取流程模型id, ...

  3. mongodb 语法小结

    数据库 一个mongodb中可以建立多个数据库. MongoDB的默认数据库为"db",该数据库存储在data目录中. MongoDB的单个实例可以容纳多个独立的数据库,每一个都有 ...

  4. Java接口继承

    Java中接口可以继承接口,并且可以多继承.

  5. APlayer 媒体播放引擎

    APlayer媒体播放引擎 Windows平台的播放内核 封闭式 DirectShow 架构,不受系统解码环境干扰 全媒体文件格式支持 丰富的媒体文件传输协议(http/https/ftp/mms/r ...

  6. xmake-vscode插件开发过程记录

    最近打算给xmake写一些IDE和编辑器的集成插件,发现vscode的编辑器插件比较容易上手的,就先研究了下vscode的插件开发流程,并且完成了xmake-vscode插件的开发. 我们先来看几张最 ...

  7. [BNDSOJ] 小P的数列代码

    感谢gjznb大佬的帮助Orz #include<bits/stdc++.h> using namespace std; ; vector<int> dp[N][N]; ]; ...

  8. [常用类]时间内Date、SimpleDateFormat、Calendar类

    Date类的概述是util包下的,不能导入sql包的.* 类 Date 表示特定的瞬间,精确到毫秒. *构造方法 * public Date() * public Date(long date) 如果 ...

  9. Django 数据库多字段同时关联一个表为外键的解决办法

    多个字段对应一个外键时,会报错,如: class Storehouse_list(models.Model):#库位列表 nid = models.AutoField(primary_key=True ...

  10. CVE-2016-0822-MTK-drivers/misc/mediatek/connectivity/common/combo/linux/wmt_dev.c#1158

    CVE-2016-0822-MTK-drivers/misc/mediatek/connectivity/common/combo/linux/wmt_dev.c#1158 //mediatek/ke ...