spring boot 自定义注解实现自动打印方法日志(入参和返回值)

  • pom文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.4.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.aline</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>demo</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.7</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

  • 定义一个日志注解
    SysLog.java
package com.aline.demo.annotation;

import java.lang.annotation.*;

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

  • 定义一个日志实例缓存
  • LoggerCache.class
package com.aline.demo.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;

public class LoggerCache {

    /**
     * 日志实例记录在内存中
     */
    private static HashMap<String, Logger> LOGERS = new HashMap<String, Logger>();

    /**
     * 根据类名获取缓存的日志实例
     * @param className 包名加类名 this.getClass().getName();
     * @return
     */
    public static Logger getLoggerByClassName(String className) {
    	// 从静态map中获取日志实例
        Logger logger = LOGERS.get(className);
        // 如果没取到
        if (logger == null) {
        	// 创建一个日志实例
            logger = LoggerFactory.getLogger(className);
            // 加入到静态map中
            LOGERS.put(className, logger);
        }
        // 返回
        return logger;
    }

}
  • 定义一个切面实现日志记录

SysLogAspect.java

package com.aline.demo.aspect;

import com.alibaba.fastjson.JSON;
import com.aline.demo.util.LoggerCache;
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.stereotype.Component;

import java.lang.reflect.Method;

@Aspect
@Component
public class SysLogAspect {

    @Pointcut("@annotation(com.aline.demo.annotation.SysLog)")
    public void log() {
    }

    /**
     * 加入注解自动记录方法日志
     *
     * @param joinPoint
     * @return
     * @throws Throwable
     */
    @Around(value = "log()")
    public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
    	// 获取执行方法的类的名称(包名加类名)
   		String className = joinPoint.getTarget().getClass().getName();
   		// 获取实例和方法
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        // 从缓存中获取日志实例
        Logger log = LoggerCache.getLoggerByClassName(className);
        // 记录日志
        log.info(className + "." + method.getName() + "() 执行");
        Object[] args = joinPoint.getArgs();
        log.info("Params\t===》\t" + JSON.toJSONString(args));
        // 执行方法获取返回值
        Object proceed = joinPoint.proceed();
        // 记录日志
        log.info("Returns\t===》\t" + JSON.toJSONString(proceed));
        // 返回
        return proceed;
    }
    
}
  • 写个controller测试
    TestController.java
package com.aline.demo.controller;

import com.aline.demo.annotation.SysLog;
import com.aline.demo.util.LoggerCache;
import org.slf4j.Logger;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.text.SimpleDateFormat;
import java.util.Date;

@RestController
@RequestMapping("/test")
public class TestController {

    static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");

    @GetMapping("/now")
    public String now(){
    	// 从缓存中获取日志
        Logger LOG = LoggerCache.getLoggerByClassName(this.getClass().getName());
        LOG.info("自定义日志 ==》 日志内容。。。");
        return sdf.format(new Date());
    }

    @GetMapping("/hello")
    @SysLog()
    public String hello(String name){
        return "Hello, " + name;
    }

}

访问 http://localhost:8080/test/hello?name=aline
打印日志:

2019-05-09 16:58:20.410  INFO 40004 --- [nio-8080-exec-1] c.aline.demo.controller.TestController   : com.aline.demo.controller.TestController.hello() 执行,参数 ==2019-05-09 16:58:20.584  INFO 40004 --- [nio-8080-exec-1] c.aline.demo.controller.TestController   : Params	===["aline"]
2019-05-09 16:58:20.598  INFO 40004 --- [nio-8080-exec-1] c.aline.demo.controller.TestController   : Returns	==="Hello, aline"

访问 http://localhost:8080/now
打印日志:

2019-05-09 16:58:29.208  INFO 40004 --- [nio-8080-exec-3] c.aline.demo.controller.TestController   : 自定义日志 ==》 日志内容。。。

猜你喜欢

转载自blog.csdn.net/csdn_meng/article/details/90042731
今日推荐