springboot 自定义注解及使用,spring 日志注解

  springboot 自定义注解及使用,spring 日志注解

  

前言

在之前的日志记录的写法中,我们大多是写一个工具类,在这个类里面定义日志保存的方法,然后再控制器中执行请求的时候调用即可,虽然调用仅仅一行代码,但是不够友好;所有可以写一个类似于@控制器等的注解,在需要保存日志的方法上面加上一个注解,这样不用在每个都写一端代码;话不多说上代码

 

  

1、首先一个log的实体类,这个无关紧要

包com。系统mg。系统。域;导入Java。io。可序列化;导入Java。util。日期;导入javax。坚持。列;导入javax。坚持。产生的价值;导入javax。坚持。id;导入javax。坚持。表;导入javax。坚持。瞬态;导入com。系统mg。常见。注释。导出配置;@Table(name=t_log )公共类系统记录实现可序列化{ private static final long serial version uid=-8878596941954995444 l;@ Id @ generated value(generator= JDBC )@ Column(name= Id )private Long Id;@ Column(name= USERNAME )@ export config(value=操作用户)私有字符串用户名;@ Column(name= OPERATION )@ export config(value=描述)私有字符串操作;@ Column(name= TIME )@ export config(value=耗时(毫秒))私长时间;@ Column(name= METHOD )@ export config(value=操作方法)私有字符串方法;@ Column(name= PARAMS )@ export config(value=参数)私有字符串参数;@ Column(name= IP )@ export配置(value= IP地址)私串IP;@ Column(name= CREATE _ TIME )@ export config(value=操作时间,convert= c : com。系统mg。常见。util。poi。转换。时间转换’)私人日期创建时间;@ Column(name= LOCATION )@ export config(value=地点)私有字符串位置;//用于搜索条件中的时间字段@瞬态私有字符串time field/* * * * @ return ID */public Long getId(){ return ID;}/* * * * @ param id */public void setId(Long id){ this。id=id}/* * * * * *返回用户名*/public String get USERNAME(){返回用户名;}/* * * * @ param username */public void set username(字符串用户名){ this。用户名=用户名==空?空:用户名。trim();}/* * * * @ return OPERATION */public String get OPERATION(){ return OPERATION;}/* * * * @ param operation */public void set操作(字符串操作){ this。operation=operation==null?空

 

   : operation.trim();    }     /**     * @return TIME     */    public Long getTime() {        return time;    }     /**     * @param time     */    public void setTime(Long time) {        this.time = time;    }     /**     * @return METHOD     */    public String getMethod() {        return method;    }     /**     * @param method     */    public void setMethod(String method) {        this.method = method == null ? null : method.trim();    }     /**     * @return PARAMS     */    public String getParams() {        return params;    }     /**     * @param params     */    public void setParams(String params) {        this.params = params == null ? null : params.trim();    }     /**     * @return IP     */    public String getIp() {        return ip;    }     /**     * @param ip     */    public void setIp(String ip) {        this.ip = ip == null ? null : ip.trim();    }     /**     * @return CREATE_TIME     */    public Date getCreateTime() {        return createTime;    }     /**     * @param createTime     */    public void setCreateTime(Date createTime) {        this.createTime = createTime;    }     public String getLocation() {        return location;    }     public void setLocation(String location) {        this.location = location;    }     public String getTimeField() {        return timeField;    }     public void setTimeField(String timeField) {        this.timeField = timeField;    }     }

2、定义一个注解接口

package com.sysmg.common.annotation; import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target; @Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)public @interface Log {    String value() default "";}

@Target(ElementType.METHOD)代表是方法上的注解,当然也可以是类注解,字段注解等

 

  @Target(ElementType.TYPE) //接口、类、枚举、注解@Target(ElementType.FIELD) //字段、枚举的常量@Target(ElementType.METHOD) //方法@Target(ElementType.PARAMETER) //方法参数@Target(ElementType.CONSTRUCTOR) //构造函数@Target(ElementType.LOCAL_VARIABLE)//局部变量@Target(ElementType.ANNOTATION_TYPE)//注解@Target(ElementType.PACKAGE) ///包

  @Retention(RetentionPolicy.RUNTIME)代表注解会被jvm保留,这个参数有三种

  RetentionPolicy.SOURCE —— 这种类型的Annotations只在源代码级别保留,编译时就会被忽略RetentionPolicy.CLASS —— 这种类型的Annotations编译时被保留,在class文件中存在,但JVM将会忽略RetentionPolicy.RUNTIME —— 这种类型的Annotations将被JVM保留,所以他们能在运行时被JVM或其他使用反射机制的代码所读取和使用。一般默认第三种

  当然也可以写

  @Documented和@Order(优先级 数字越小优先级越高)

  @Documented 注解表明这个注解应该被 javadoc工具记录. 默认情况下,javadoc是不包括注解的. 但如果声明注解时指定了 @Documented,则它会被 javadoc 之类的工具处理, 所以注解类型信息也会被包括在生成的文档中。

  @Order标记定义了组件的加载顺序,这个标记包含一个value属性。属性接受整形值。如:1,2 等等。值越小拥有越高的优先级。Ordered.HIGHEST_PRECEDENCE这个属性值是最高优先级的属性,它的值是-2147483648,对应的最低属性值是Ordered.LOWEST_PRECEDENCE,它的值是2147483647。

  String value() default ""

  这个代表是要传递的参数,类似

  

@Autowired(required=true)  public @interface Autowired {     /**     * Declares whether the annotated dependency is required.     * <p>Defaults to {@code true}.     */    boolean required() default true; }

springmvc项目还需要开启切面编程

 

  

<aop:aspectj-autoproxy proxy-target-class="true"/>

springboot默认是开启的

 

  

3、定义注解的实现类,也就是这个注解要做什么事

package com.sysmg.common.aspect; import java.lang.reflect.Method;import java.util.Date; import javax.servlet.http.HttpServletRequest; import org.apache.shiro.SecurityUtils;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.springframework.beans.factory.annotation.Autowired;import org.springframework.core.LocalVariableTableParameterNameDiscoverer;import org.springframework.stereotype.Component; import com.fasterxml.jackson.databind.ObjectMapper;import com.sysmg.common.annotation.Log;import com.sysmg.common.util.AddressUtilsBak;import com.sysmg.common.util.HttpContextUtils;import com.sysmg.common.util.IPUtils;import com.sysmg.system.domain.SysLog;import com.sysmg.system.domain.User;import com.sysmg.system.service.LogService; @Aspect@Componentpublic class LogAspect {     @Autowired    private LogService logService;     @Autowired    ObjectMapper mapper;     @Pointcut("@annotation(com.sysmg.common.annotation.Log)")    public void pointcut() {    }     @Around("pointcut()")    public Object around(ProceedingJoinPoint point) {        Object result = null;        long beginTime = System.currentTimeMillis();        try {            result = point.proceed();        } catch (Throwable e) {            e.printStackTrace();        }        long time = System.currentTimeMillis() - beginTime;        saveLog(point, time);        return result;    }     private void saveLog(ProceedingJoinPoint joinPoint, long time) {        User user = (User) SecurityUtils.getSubject().getPrincipal();        MethodSignature signature = (MethodSignature) joinPoint.getSignature();        Method method = signature.getMethod();        SysLog log = new SysLog();        Log logAnnotation = method.getAnnotation(Log.class);        if (logAnnotation != null) {            log.setOperation(logAnnotation.value());        }        String className = joinPoint.getTarget().getClass().getName();        String methodName = signature.getName();        log.setMethod(className + "." + methodName + "()");        Object[] args = joinPoint.getArgs();        LocalVariableTableParameterNameDiscoverer u = new LocalVariableTableParameterNameDiscoverer();        String[] paramNames = u.getParameterNames(method);        if (args != null && paramNames != null) {            String params = "";            for (int i = 0; i < args.length; i++) {                params += "  " + paramNames[i] + ": " + args[i];            }            log.setParams(params);        }        HttpServletRequest request = HttpContextUtils.getHttpServletRequest();        log.setIp(IPUtils.getIpAddr(request));        log.setUsername(user.getUsername());        log.setTime(time);        log.setCreateTime(new Date());        log.setLocation(AddressUtilsBak.getRealAddressByIP(log.getIp(), mapper));        this.logService.save(log);    }}

这里的实现类中日志添加的方法中使用的淘宝的获取ip服务,后续会加上去,其实这里面可以随便写一个实现方法,因为我是留工具备份,所以记录的较多

 

  具体的@Aspect、@Pointcut、@Around、@Before、@After等aop相关的注解和参数需要自己去巩固一下知识

  

4、然后就可以在你想要记录日志的地方使用即可

package com.sysmg.controller; import java.util.List;import java.util.Map; import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.ResponseBody; import com.github.pagehelper.PageHelper;import com.github.pagehelper.PageInfo;import com.sysmg.common.annotation.Log;import com.sysmg.common.domain.QueryRequest;import com.sysmg.common.domain.ResponseBo;import com.sysmg.common.util.FileUtils; @Controllerpublic class TestController{     @Log("规则")    @RequestMapping("test")    public String index() {        return "test";    }}

大概这样就可以使用了,目前里面缺少aop相关知识的介绍以及获取访问ip的工具类,不过跟本课题关系不大,后续会更上去

 

  到此这篇关于springboot自定义日志注解的实现的文章就介绍到这了,更多相关springboot自定义日志注解内容请搜索盛行IT以前的文章或继续浏览下面的相关文章希望大家以后多多支持盛行IT!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: