springboot(十六)自定义注解

98 阅读1分钟

增加切面依赖

<dependency>  
    <groupId>org.springframework.boot</groupId>  
    <artifactId>spring-boot-starter-aop</artifactId>  
</dependency>

增加注解文件

image.png

package com.example.fastjson.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 LogExecutionTime {  
}

增加切面

package com.example.fastjson.aspect;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class LogExecutionTimeAspect {

    private static final Logger logger = LoggerFactory.getLogger(LogExecutionTimeAspect.class);

    @Around("@annotation(com.example.fastjson.annotation.LogExecutionTime)")
    public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
        long start = System.currentTimeMillis();

        Object proceed = joinPoint.proceed();

        long executionTime = System.currentTimeMillis() - start;

        logger.info("{} executed in {} ms", joinPoint.getSignature(), executionTime);
        return proceed;
    }

}

测试

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

    @GetMapping("hello")
    @LogExecutionTime
    public String hello(){
        return "hello";
    }
}

http://localhost:8080/test/hello刷新,控制台显示如下信息

image.png

进阶一

增加注解前后执行信息

@Aspect
@Component
public class LogExecutionTimeAspect {

    private static final Logger logger = LoggerFactory.getLogger(LogExecutionTimeAspect.class);

    @Pointcut("@annotation(com.example.fastjson.annotation.LogExecutionTime)")
    public void logExecutionTimePointcut() {}

    @Around("logExecutionTimePointcut()")
    public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
        long start = System.currentTimeMillis();

        Object proceed = joinPoint.proceed();

        long executionTime = System.currentTimeMillis() - start;

        logger.info("{} executed in {} ms", joinPoint.getSignature(), executionTime);
        return proceed;
    }

    @Before("logExecutionTimePointcut()")
    public void before() {
        logger.info("Before executing method with LogExecutionTime annotation");
    }

    @After("logExecutionTimePointcut()")
    public void after() {
        logger.info("After executing method with LogExecutionTime annotation");
    }
}

image.png

进阶二

class上增加注解,不必每个方法都增加上注解,使用class和方法都可以共用注解

修改LogExecutionTime

增加ElementType.TYPE 完整代码

import java.lang.annotation.ElementType;  
import java.lang.annotation.Retention;  
import java.lang.annotation.RetentionPolicy;  
import java.lang.annotation.Target;  
  
@Target({ElementType.METHOD, ElementType.TYPE})  
@Retention(RetentionPolicy.RUNTIME)  
public @interface LogExecutionTime {  
}

修改LogExecutionTimeAspect

增加@within(com.example.fastjson.annotation.LogExecutionTime) 完整代码

package com.example.fastjson.aspect;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class LogExecutionTimeAspect {

    private static final Logger logger = LoggerFactory.getLogger(LogExecutionTimeAspect.class);

    @Pointcut("@within(com.example.fastjson.annotation.LogExecutionTime) || @annotation(com.example.fastjson.annotation.LogExecutionTime)")
    public void logExecutionTimePointcut() {}

    @Around("logExecutionTimePointcut()")
    public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
        long start = System.currentTimeMillis();

        Object proceed = joinPoint.proceed();

        long executionTime = System.currentTimeMillis() - start;

        logger.info("{} executed in {} ms", joinPoint.getSignature(), executionTime);
        return proceed;
    }

    @Before("logExecutionTimePointcut()")
    public void before() {
        logger.info("Before executing method with LogExecutionTime annotation");
    }

    @After("logExecutionTimePointcut()")
    public void after() {
        logger.info("After executing method with LogExecutionTime annotation");
    }
}

测试

image.png