自动添加日志记录,@Log注解,日志切面

在controller的方法上添加注解@Log(description = "重置密码",logType = LogEnum.UPDATE)实现将日志记录添加到表中

切入点log.java



import java.lang.annotation.*;



@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Log {

    /**
     * 操作系统(4A、督导员、督导员App等)
     */
    String operatingSystem() default "";

    /**
     * 操作模块
     */
    String module() default "";

    /**
     * 操作描述
     */
    String description() default "";

    /**
     * 操作类型 查询 删除 保存
     */
    String logType() default "";
}

 LogHandle.java




import lombok.extern.slf4j.Slf4j;
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.springframework.core.Ordered;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.lang.reflect.Method;


@Aspect
@Component
@Slf4j
public class LogHandle implements Ordered {
    @Resource
    private LogService logService;

    /**
     * 日志切入点
     */
    @Pointcut("@annotation(上面log的文件路径xxx.xxx.xxx.log)")
    public void logPointCut(){}

    @AfterReturning(pointcut = "logPointCut()")
    public void doAfter(JoinPoint joinPoint){
        log.info("----进入切面----");
        /**
         * 解析Log注解
         */
        String methodName = joinPoint.getSignature().getName();
        Method method = currentMethod(joinPoint,methodName);
        Log log = method.getAnnotation(Log.class);
        logService.put(joinPoint,methodName,log.operatingSystem(),log.module(),log.description(),log.logType());
    }

    /**
     * 获取当前执行的方法
     *
     * @param joinPoint  连接点
     * @param methodName 方法名称
     * @return 方法
     */
    private Method currentMethod(JoinPoint joinPoint, String methodName) {
        /**
         * 获取目标类的所有方法,找到当前要执行的方法
         */
        Method[] methods = joinPoint.getTarget().getClass().getMethods();
        Method resultMethod = null;
        for (Method method : methods) {
            if (method.getName().equals(methodName)) {
                resultMethod = method;
                break;
            }
        }
        return resultMethod;
    }

    @Override
    public int getOrder() {
        return 100;
    }
}

LogEnum.java



public class LogEnum {
    //operatingSystem
    public final static String SUPERVISOR  = "劳务人员办公系统";

    //logType
    public final static String SELECT  = "查询";
    public final static String UPDATE  = "保存";
    public final static String DELETE  = "删除";
}

 syslog.java



import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import java.util.Date;

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "sys_log")
public class SysLog {
    /**
     * 操作日志id
     */
    @Id
    @GeneratedValue(generator = "JDBC")
    private String id;

    /**
     * 操作时间
     */
    @Column(name = "add_time")
    private Date addTime;

    /**
     * 操作人Id
     */
    @Column(name = "user_id")
    private String userId;

    /**
     * 操作人姓名
     */
    @Column(name = "user_name")
    private String userName;

    /**
     * IP
     */
    @Column(name = "IP")
    private String ip;


    /**
     * 操作描述
     */
    private String description;

    /**
     * 操作类型 查询 删除 保存
     */
    @Column(name = "log_type")
    private String logType;


    /**
     * 入参
     */
    private String params;


}

 logserver.java


import cn.dev33.satoken.stp.StpUtil;
import com.alibaba.fastjson.JSONObject;


import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.javassist.*;
import org.apache.ibatis.javassist.bytecode.CodeAttribute;
import org.apache.ibatis.javassist.bytecode.LocalVariableAttribute;
import org.apache.ibatis.javassist.bytecode.MethodInfo;
import org.aspectj.lang.JoinPoint;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.*;


@Slf4j
@Service
public class LogService {
    @Resource
    private SysLogMapper sysLogMapper;



    public void put(JoinPoint joinPoint, String methodName, String operatingSystem,String module, String description, String logType) {
        try {
            log.info("保存用户操作记录");
            //ip
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            //设备信息(从前端获取)  从header里面获取参数
            String deviceInfo = request.getHeader("deviceInfo");
            // 拿到ip地址
            String ip = IpUtils.getIpAdrress(request);
            //获取方法的形参
            String params = this.operateContent(joinPoint,methodName,request);
            String userId="";
            String userName = "";
       
          

			// 代码保存日志逻辑
            if (!logType.equals(LogEnum.SELECT)){
                SysLog sysLog = SysLog.builder().id(FunctionUtil.GenerateGUID())
                        .addTime(new Date())
                        .userId(userId)
                        .userName(userName)
                        .ip(ip)
                        .description(description)
                        .logType(logType)
                        .params(params)
                        .build();
                sysLogMapper.insertSelective(sysLog);
            }
            //保存方法日志到文件中
            /*String url = request.getServletPath() + "/" + methodName;
            xxxx xxx= xxx.xxx("xxx");
            File file = LogInfo.createFile(xxx.getxxx());
            LogInfo.saveLog(file,ip,userId,deviceInfo,url,params);*/
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public String operateContent(JoinPoint joinPoint, String methodName, HttpServletRequest request) throws ClassNotFoundException, NotFoundException {
        String className = joinPoint.getTarget().getClass().getName();
        Object[] params = joinPoint.getArgs();
        String classType = joinPoint.getTarget().getClass().getName();
        Class<?> clazz = Class.forName(classType);
        String clazzName = clazz.getName();
        Map<String,Object > nameAndArgs = getFieldsName(this.getClass(), clazzName, methodName,params);
        StringBuffer bf = new StringBuffer();
        if (!CollectionUtils.isEmpty(nameAndArgs)){
            Iterator it = nameAndArgs.entrySet().iterator();
            while (it.hasNext()){
                Map.Entry entry = (Map.Entry) it.next();
                String key = (String) entry.getKey();
                String value = JSONObject.toJSONString(entry.getValue());
                bf.append(key).append("=");
                //bf.append(value).append("&");
                bf.append(value);
            }
        }
        if (StringUtils.isEmpty(bf.toString())){
            bf.append(request.getQueryString());
        }
        return bf.toString();
    }

    private Map<String,Object> getFieldsName(Class cls, String clazzName, String methodName, Object[] args) throws NotFoundException {
        Map<String,Object > map=new HashMap<String,Object>();

        ClassPool pool = ClassPool.getDefault();
        ClassClassPath classPath = new ClassClassPath(cls);
        pool.insertClassPath(classPath);

        CtClass cc = pool.get(clazzName);
        CtMethod cm = cc.getDeclaredMethod(methodName);
        MethodInfo methodInfo = cm.getMethodInfo();
        CodeAttribute codeAttribute = methodInfo.getCodeAttribute();
        LocalVariableAttribute attr = (LocalVariableAttribute) codeAttribute.getAttribute(LocalVariableAttribute.tag);
        if (attr == null) {
            // exception
            return map;
        }
        int pos = Modifier.isStatic(cm.getModifiers()) ? 0 : 1;
        for (int i = 0; i < cm.getParameterTypes().length; i++){
            map.put( attr.variableName(i + pos),args[i]);//paramNames即参数名
        }
        return map;
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java自定义注解和AOP切面是两个不同的概念,但它们可以结合使用来实现一些非常有用的功能。 Java自定义注解是Java语言中的一种特殊的语法结构,它允许开发者在代码中添加一些元数据,以便后续处理程序能够基于这些元数据来进行特定的操作。Java自定义注解可以在类、方法、属性等各种代码元素上进行声明,并且可以指定注解的属性,以提供更多的元数据信息。 AOP(面向切面编程)是一种编程思想,它允许开发者在不改变原有代码的情况下,通过添加额外的代码来实现某些横切关注点的功能。AOP切面是一个包含一组通知(Advice)和切点(Pointcut)的类,它可以在程序运行时自动拦截指定的方法或类,并执行相应的通知。 在Java中,我们可以通过将自定义注解和AOP切面结合使用,来实现一些非常有用的功能。例如,我们可以定义一个名为 @Log注解,在程序中使用该注解来标记需要记录日志的方法,然后编写一个AOP切面来拦截这些方法,并在方法执行前后记录日志。这样,我们就可以轻松地实现统一的日志记录功能,而不需要在每个方法中都编写日志记录代码。 下面是一个简单的示例代码,演示了如何使用Java自定义注解和AOP切面来实现统一的日志记录功能: ```java // 定义一个名为 @Log注解 @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface Log { } // 编写一个AOP切面,拦截带有 @Log 注解的方法,并记录日志 @Aspect @Component public class LogAspect { @Around("@annotation(log)") public Object around(ProceedingJoinPoint joinPoint, Log log) throws Throwable { String methodName = joinPoint.getSignature().getName(); System.out.println("方法 " + methodName + " 开始执行..."); Object result = joinPoint.proceed(); System.out.println("方法 " + methodName + " 执行完成,返回值为:" + result); return result; } } // 在程序中使用 @Log 注解标记需要记录日志的方法 @Service public class UserService { @Log public String getUserInfo(String userId) { // ... } } ``` 在上面的代码中,我们首先定义了一个名为 @Log注解,并指定了它的作用范围为方法。然后,我们编写了一个AOP切面 LogAspect,使用 @Around 注解来指定切点为所有带有 @Log 注解的方法。在切面的 around 方法中,我们通过 ProceedingJoinPoint 对象获取当前执行的方法名,并在方法执行前后打印日志。最后,我们在 UserService 类的 getUserInfo 方法上使用了 @Log 注解,表示这个方法需要记录日志。 当程序运行时,LogAspect 切面自动拦截 UserService 类的 getUserInfo 方法,并执行 around 方法中的逻辑,从而实现了统一的日志记录功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值