基于Spring AOP的用户日志实现
程序员文章站
2022-07-12 14:57:42
...
1.数据库中建立对应的table sys_log
然后生成对应的bean,dao,service等等
2.在springmvc的配置文件中添加aop的配置
<!-- 启动AOP AspectJ注解自动代理 -->
<aop:aspectj-autoproxy />
<!-- 通知spring使用cglib而不是jdk的来生成代理方法 AOP可以拦截到Controller -->
<aop:config proxy-target-class="true"></aop:config>
3.自定义注解
package com.mqb.logAbout.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 自定义注解类
* @author MQB
*
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
public @interface ArchivesLog {
/**
* 操作说明
* @return
*/
public String operateContent() default "";
}
关于@Retention,@Target等注解为java的四种元注解中的注解,详细信息可以看张开涛大佬的博客
https://www.iteye.com/blog/wisfly-2289443
4.创建一个切点类
package com.mqb.logAbout.log;
import java.lang.reflect.Method;
import java.util.Date;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import com.mqb.bean.User;
import com.mqb.logAbout.annotation.ArchivesLog;
import com.mqb.service.SysLogService;
@Aspect
@Component
public class ArchivesLogAspect {
@Autowired
private SysLogService slService;
private static final Logger logger=LoggerFactory.getLogger(ArchivesLog.class);
/**
* 定义一个切入点函数,对controller层
* 中有ArchivesLog注解的方法进行拦截
*/
@Pointcut("@annotation(com.mqb.logAbout.annotation.ArchivesLog)")
public void controllerAspect() {}
/**
* 方法返回后进行操作,记录日志,存入数据库
* @param joinPoint 连接点,被拦截的函数
* @throws Exception
*/
@Before("controllerAspect()")
public void doBefore(JoinPoint joinPoint) throws Exception{
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
HttpSession session=request.getSession();
User user=(User) session.getAttribute("user");
String ip=request.getRemoteAddr();
try {
//===========控制台输出===============//
System.out.println("====前置通知开始====");
System.out.println("请求方法:"+ (joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName() + "()"));
System.out.println("方法描述:"+getControllerMethodDescription(joinPoint));
System.out.println("请求人:" + user.getName());
System.out.println("请求IP:" + ip);
}catch(Exception e) {
logger.error("==前置通知异常");
logger.error("异常信息:{}",e.getMessage());
}
}
public static String getControllerMethodDescription(JoinPoint joinPoint) throws Exception {
String targetName = joinPoint.getTarget().getClass().getName();
String methodName = joinPoint.getSignature().getName();
Object[] arguments = joinPoint.getArgs();
Class targetClass = Class.forName(targetName);
Method[] methods = targetClass.getMethods();
String description = "";
for (Method method : methods) {
if (method.getName().equals(methodName)) {
Class[] clazzs = method.getParameterTypes();
if (clazzs.length == arguments.length) {
description = method.getAnnotation(ArchivesLog.class).operateContent();
break;
}
}
}
return description;
}
}
@annotation注解只针对方法,若想实现在类上加注解,使类内所有方法都执行切点内的方法,则需要使用@within了
这里还没有存入数据库,只是控制台输出下,看下效果。
5.在需要添加日志的方法中加上注解,如
/**
* 跳转到project/waitingList页面
* @param model
* @return
*/
@ArchivesLog(operateContent="查看待审批列表")
@RequestMapping("/waitingList")
public ModelAndView waitingList(ModelAndView model) {
model.setViewName("project/waitingList");
return model;
}
6.在这个方法打个断点执行下,可以看到控制的输出
后面只要在控制台输出的位置加上添加到数据库就可以了,后续一些特殊需要的功能就需要自己实现了
参考两位大佬的博客,基本都是模仿他们实现的
https://blog.csdn.net/czmchen/article/details/42392985
https://www.cnblogs.com/mei-m/p/10231792.html
上一篇: Revit二次开发之创建倾斜楼板(Create a slope floor / slab)
下一篇: revit 2020 二次开发——在楼板上挖圆形洞(Create circle openning in floor)
推荐阅读
-
spring aop action中验证用户登录状态的实例代码
-
基于jQuery实现的Ajax 验证用户名唯一性实例代码
-
jsp基于XML实现用户登录与注册的实例解析(附源码)
-
Spring中的JDBCTemplate、Spring基于AOP的事务控制、Spring中的事务控制
-
jQuery基于ajax实现页面加载后检查用户登录状态的方法
-
python3实现基于用户的协同过滤
-
Spring AOP的实现原理详解及实例
-
基于代理类实现Spring AOP
-
基于Laravel Auth自定义接口API用户认证的实现方法
-
基于log4net的日志组件扩展分装,实现自动记录交互日志 XYH.Log4Net.Extend