SpringBoot自定义starter+注解+AOP实现日志收集

什么是starter

starter是SpringBoot中的一个非常重要的概念,相当于模块,它能将模块所需的依赖整合起来并对模块内的Bean根据环境(条件)进行自动配置。使用者只需要依赖相应功能的starter,无需做过多的配置和依赖,就能自动扫描并加载相应的模块。

为什么用starter

1、整合了这个模块需要的依赖库;
2、提供模块的配置项给使用者;
3、提供自动配置类对模块内的Bean进行自动装配。

怎么用

自定义starter+ 自定义注解+ AOP = 日志记录

1. 依赖包

<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>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
</dependency>

2. 自定义注解

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ApiLog {

    /**
     * 操作类型
     * TODO 是不是可以直接传字符串呢?扩展操作的问题
     *
     * @return 操作类型枚举
     */
    OperateEnum operateType() default OperateEnum.OTHER;

    /**
     * 所属模块
     *
     * @return 所属模块名称
     */
    String operateModule() default "其他模块";

    /**
     * 是否记录请求结果
     *
     * @return 布尔值,默认false
     */
    boolean recordResult() default false;

}

3. 切面类+暴露接口

@Aspect
@Slf4j
public class OperationLoggingAspect {

    @Autowired
    private OperationLoggingExecutor operationLoggingExecutor;

    @Pointcut("@annotation(com.api.ApiLog)")
    public void pointcut() {
    }

    @Around("pointcut()")
    public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        // 记录异常信息
        String errorCode = null;

        // 处理业务,并透传业务异常
        Object result = null;
        try {
            result = proceedingJoinPoint.proceed();
        } catch (Exception ex) {
            errorCode = ex.getMessage();
            throw ex;
        } finally {
            // 记录日志
            saveLog(proceedingJoinPoint, errorCode);
        }
        return result;
    }

    private void saveLog(ProceedingJoinPoint proceedingJoinPoint, String errorCode) {
        try {
            // 获取基础参数
            RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
            ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) requestAttributes;
            HttpServletRequest httpServletRequest = servletRequestAttributes.getRequest();
            Object[] args = proceedingJoinPoint.getArgs();
            MethodSignature signature = (MethodSignature) proceedingJoinPoint.getSignature();
            Method method = signature.getMethod();
            ApiLog apiLog = method.getAnnotation(ApiLog.class);
            operationLoggingExecutor.saveLog(httpServletRequest, apiLog, args, errorCode);
        } catch (Exception ex) {
            log.error("发送日志发生异常", ex);
        }
    }

}

4. 配置类

@Configuration
public class OperationLoggingAutoConfiguration {

    @Bean
    public OperationLoggingAspect operationLoggingAspect() {
        return new OperationLoggingAspect();
    }

}

5. 配置spring.factories,指明starter的主入口,在resources目录下建META-INF目录,创建spinrg.factories文件,文件内容如下:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.configure.OperationLoggingAutoConfiguration
执行mvn install部署到本地maven仓库或者通过mvn deploy部署到公司私有仓库。

6. 使用

@PostMapping("test")
@ApiLog(operateType = OperateEnum.QUERY, operateModule = "测试模块", recordResult = true)
public WebResponse test() {}

你可能感兴趣的:(java,SpringBoot,java,spring,boot,aop)