全局添加日志-自定义注解

好久没有写博客了,最近找一些之前写过的代码,结果不知道在那个项目里面写的,已经找不到了,又得从头开始,所以记录一下本次编写过程,之后自己查看,也可给需要的朋友一个参考!

项目为 springboot2.0+mybatisplus + mysql搭建

需求:编写一个注解,记录 登录账户的操作记录,主要记录增删改操作

效果如下图所示

1.首先添加一个自定义注解,@interface ,里面的注解类型元素(参数)是需要在具体注解里面添加的,可以有很多类型如string,int,array等,注意,对参数有一下要求:

*访问修饰符必须为public,不写默认为public;

*名称一般定义为名词,如果注解中只有一个元素,请把名字起为value(后面使用会带来便利操作)

*default代表默认值 如这样: int age() default 18;

*如果没有默认值,代表后续使用注解时必须给该类型元素赋值

*所有定义的注解都会自动继承java.lang.annotation.Annotation接口

@Target注解,是专门用来限定某个自定义注解能够被应用在哪些Java元素上面的。它使用一个枚举类型定义如下:

public enum ElementType {
    /** 类,接口(包括注解类型)或枚举的声明 */
    TYPE,

    /** 属性的声明 */
    FIELD,

    /** 方法的声明 */
    METHOD,

    /** 方法形式参数声明 */
    PARAMETER,

    /** 构造方法的声明 */
    CONSTRUCTOR,

    /** 局部变量声明 */
    LOCAL_VARIABLE,

    /** 注解类型声明 */
    ANNOTATION_TYPE,

    /** 包的声明 */
    PACKAGE
}

@Retention注解,翻译为持久力、保持力。即用来修饰自定义注解的生命力。
注解的生命周期有三个阶段:1、Java源文件阶段SOURCE;2、编译到class文件阶段CLASS;3、运行期阶段RUNTIME。

具体代码如下:

package com.zdxf.server.component.security.oplog.annotation;

import com.zdxf.server.component.security.oplog.service.impl.OperationLogAnnotation;

import javax.validation.Constraint;
import java.lang.annotation.*;

/**
 * 操作日志注解
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
// 可以出现在java文档中
@Documented
// 可以被子注解继承
@Inherited
public @interface AddOperationLog {

    /**
     * 功能
     * @return
     */
    String resource() default "";

    /**
     * 操作
     * @return
     */
    String operation() default "";

    /**
     * 模块
     * @return
     */
    String module() default "";
}

2. 然后添加一个spring拦截器,拦截所有请求,也可以指定到方法,将dao注入进去,否则报空指针

package com.zdxf.server.component.security.oplog.config;

import com.zdxf.server.component.security.oplog.dao.IOperationLogDao;
import com.zdxf.server.component.security.oplog.service.impl.OperationLogAnnotation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class AnnotationConfig implements WebMvcConfigurer {
    @Autowired
    private IOperationLogDao dao;
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        OperationLogAnnotation oper=new OperationLogAnnotation(dao);
        registry.addInterceptor(oper)
                .addPathPatterns("/**");
    }
}

3.保存登录账户信息

package com.zdxf.server.component.security.oplog.service.impl;

import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zdxf.server.common.base.context.RequestContext;
import com.zdxf.server.common.base.model.UserPriciple;
import com.zdxf.server.component.common.util.SecurityUserUtil;
import com.zdxf.server.component.govern.model.TplUserT;
import com.zdxf.server.component.security.oplog.annotation.AddOperationLog;
import com.zdxf.server.component.security.oplog.dao.IOperationLogDao;
import com.zdxf.server.component.security.oplog.model.OperationLogVO;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.Date;

@Aspect
@Component
public class OperationLogAnnotation implements HandlerInterceptor {

    private IOperationLogDao dao;
    public OperationLogAnnotation(IOperationLogDao dao){
        this.dao=dao;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
        boolean isAnn=handler.getClass().isAssignableFrom(HandlerMethod.class);

        if(isAnn) {
            //根据当前方法获取类的注解
            AddOperationLog olog=((HandlerMethod)handler).getMethodAnnotation(AddOperationLog.class);
            if(null!=olog){
                OperationLogVO op=createOperationLog(olog);
                int result=dao.insert(op);
                System.out.println("保存操作记录:"+result);
            }
        }
    }

    private OperationLogVO createOperationLog(AddOperationLog operationLog) {
        String moduleStr = operationLog.module();
        String resourceStr = operationLog.resource();
        String operationStr = operationLog.operation();
        OperationLogVO opLog = new OperationLogVO();

        UserPriciple user = RequestContext.getCurrent().getUser();
        if(null != user){
            opLog.setUserId(RequestContext.getCurrent().getUser().getId());
            opLog.setUsername(RequestContext.getCurrent().getUser().getUsername());
            opLog.setPhone(RequestContext.getCurrent().getUser().getPhone());
        }

        TplUserT tuser= SecurityUserUtil.obtainUser();
        if(null != tuser){
            opLog.setUserId(SecurityUserUtil.obtainUser().getAgencyUserId());
            opLog.setUsername(SecurityUserUtil.obtainUser().getUsername());
            opLog.setPhone(SecurityUserUtil.obtainUser().getPhone());
        }

        opLog.setOpDate(new Date());
        opLog.setIp(RequestContext.getCurrent().getRequest().getRemoteAddr());
        //    opLog.setLocalIp(RequestContext.getCurrent().getRequest().getLocalAddr());
        opLog.setModule(moduleStr);
        opLog.setResource(resourceStr);
        opLog.setOperation(operationStr);
//        opLog.setCreationDate(new Date());
        opLog.setOpCode("操作成功");
        return opLog;
    }

}

4. 对应的dao层,使用mybatis默认方法

package com.zdxf.server.component.security.oplog.dao;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zdxf.server.component.security.oplog.model.OperationLogVO;

public interface IOperationLogDao extends BaseMapper<OperationLogVO> {
}

5.对应的实体,添加@Data注解,可以代替getset方法,具体可自行查询

package com.zdxf.server.component.security.oplog.model;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;

import java.io.Serializable;
import java.util.Date;

@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("tpl_operation_log_t")
@ApiModel(value="操作日志对象", description="")
public class OperationLogVO implements Serializable {

    private static final long serialVersionUID = 1L;

    @ApiModelProperty(value = "ID(操作日志)")
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;

    @ApiModelProperty(value = "用户ID")
    private Long userId;

    @ApiModelProperty(value = "操作结果")
    private String opCode;

    @ApiModelProperty(value = "手机")
    private String phone;

    @ApiModelProperty(value = "姓名")
    private String username;

    @ApiModelProperty(value = "角色")
    private String role;

    @ApiModelProperty(value = "IP")
    private String ip;

    @ApiModelProperty(value = "操作日期")
    private Date opDate;

    @ApiModelProperty(value = "模块")
    private String module;

    @ApiModelProperty(value = "资源")
    private String resource;

    @ApiModelProperty(value = "操作")
    private String operation;

    @ApiModelProperty(value = "创建时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date creationDate;
}

6 具体应用,名称为自定义注解的名称,里面的参数就是自定义注解里面的三个参数

以上!!!

猜你喜欢

转载自blog.csdn.net/Amos_liu/article/details/108792383