这是我参与 8 月更文挑战的第 15 天,活动详情查看: 8月更文挑战
5. mapper层
LogMapper
package com.tjm.mapper;
import com.tjm.pojo.SysLog;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
@Repository
@Mapper
public interface LogMapper {
int insertLog(SysLog log);
}
然后在resources/mapper下新建一个LogMapper.xml,代码如下:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.tjm.mapper.LogMapper">
<insert id="insertLog" parameterType="SysLog" >
insert into "SysLog"("log_id","username","class_name","method_name","args")
values(#{log_id},#{username},#{class_name},#{method_name},#{args})
</insert>
</mapper>
6. 自定义操作日志记录的注解
在config目录下新建一个名为Log的Annotation文件。
package com.tjm.config;
import java.lang.annotation.*;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Log {
String value() default "";
}
之后,我们在类的前面@Log就可以使用这个我们自定义的注解。
7. 自定义操作日志切面类
同样在config目录下,新建一个LogAsPect.java,代码如下:
package com.tjm.config;
import com.tjm.pojo.SysLog;
import com.tjm.pojo.User;
import com.tjm.service.SysLogService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.util.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.sql.SQLException;
import java.util.Arrays;
@Aspect
@Component
public class LogAsPect {
private final static Logger log = org.slf4j.LoggerFactory.getLogger(LogAsPect.class);
@Autowired
private SysLogService sysLogService;
//表示匹配带有自定义注解的方法
@Pointcut("@annotation(com.tjm.config.Log)")
public void pointcut()
{
}
@Around("pointcut()")
public Object around(ProceedingJoinPoint point) {
Object result = null;
long beginTime = System.currentTimeMillis();
try {
log.info("我在目标方法之前执行!");
result = point.proceed();
//log.info((String) result);
long endTime = System.currentTimeMillis();
insertLog(point,endTime-beginTime);
} catch (Throwable e) {
}
return result;
}
//主健自增!
private static int initId = 1;
private void insertLog(ProceedingJoinPoint point,long time) {
// 从切面织入点处通过反射机制获取织入点处的方法
MethodSignature signature = (MethodSignature)point.getSignature();
//获取切入点所在的方法
Method method = signature.getMethod();
SysLog sys_log = new SysLog();
//请求的类名
String className = point.getTarget().getClass().getName();
//请求的方法名
String methodName = signature.getName();
//请求的方法参数值
String args = Arrays.toString(point.getArgs());
//从session中获取当前登录的人id
User user = (User) SecurityUtils.getSubject().getPrincipal();
String username = user.getUsername();
sys_log.setLog_id(initId++);
sys_log.setUsername(username);
sys_log.setClass_name(className);
sys_log.setMethod_name(methodName);
sys_log.setArgs(args);
log.info("当前登陆人:{},类名:{},方法名:{},参数:{},执行时间:{}",username, className, methodName, args, time);
sysLogService.insertLog(sys_log);
}
}
8.测试
在任一个Controller文件中的方法前添加一个@Log,如在登录方法前添加@Log。
执行登录方法,控制台得到如下输出:
INFO 19283 --- [nio-8080-exec-4] com.tjm.config.LogAsPect : 当前登陆人:六六,类名:com.tjm.controller.LoginController,方法名:login,参数:[六六, 123, {}],执行时间:56
数据库中数据也同步更新: