系统日志优化---自定义springboot-starter日志组件供各个服务使用

在优化项目时发现各个微服务都有各自的接口调用日志逻辑,比如每个服务都定义一个aop类拦截,十分冗余,其实是可以做成starter被各个服务引用使用,前提要先了解一下springboot自动装配原理

创建springboot工程,如果是jdk8,下面的地址换成阿里的才能选

pom依赖,这里提一下maven打包插件的区别:

一、maven-compiler-plugin

maven-jar-plugin是jar包生成插件,提供了manifest的配置,生成jar包中一般存放的是.class文件已经resources目录下的东西,文件很小。

二、spring-boot-maven-plugin

从官网的介绍来看,spring-boot-maven-plugin主要目标是spring-boot的启动、停止、运行和repackage,对于打包来说那就是repackage,也就是说它实现的打包功能是重新打包,原始jar包还是由maven-jar-plugin生成的。

javascript 复制代码
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.ming</groupId>
    <artifactId>log-spring-boot-starter</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>log-spring-boot-starter</name>
    <description>log-spring-boot-starter</description>
    <properties>
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <spring-boot.version>2.6.13</spring-boot.version>
        <lombok.version>1.18.26</lombok.version>
    </properties>

    <dependencies>
        <!--aop-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
        <!--写application.yml时会有提示,即当我输入custom时,会提示custom.log.serviceName-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>${lombok.version}</version>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

<!--maven打包时,不能用spring-boot-maven-plugin打包,我用它打包没报错,给其他服务引用对应的jar时,启动报错了。需要换成maven-compiler-plugin-->
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

项目结构很简单

注解

javascript 复制代码
package com.ming.log.module.annotation;

import java.lang.annotation.*;

/**
 * 日志注解
 * @author ming
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
public @interface CustomLogAnnotation {


}

切面逻辑

javascript 复制代码
package com.ming.log.module.aop;

import com.ming.log.module.config.CustomLogProperties;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import java.lang.reflect.Method;
import java.util.Arrays;

/**
 * aop统一拦截
 * @author ming
 */
@Slf4j
@Aspect
public class CustomLogAspect {

    private CustomLogProperties customLogProperties;

    /**
     * 当一个bean没有无参构造器时,spring创建bean时,对于构造器参数会从容器中取,
     * 这里其实是省略了@Autowired,该注解可以用在方法参数上
     * @param customLogProperties
     */
    public CustomLogAspect(CustomLogProperties customLogProperties) {
        this.customLogProperties = customLogProperties;
    }

    @Around("@annotation(com.ming.log.module.annotation.CustomLogAnnotation)")
    public Object logInvoke(ProceedingJoinPoint joinPoint) throws Throwable {
        String serviceName = customLogProperties.getServiceName();
        //获取方法名称
        Signature sig = joinPoint.getSignature();
        MethodSignature mSig = (MethodSignature)sig;
        Method method = mSig.getMethod();
        String methodName = method.getName();
        Object obj = joinPoint.proceed();
        log.error("服务名:{}",serviceName);
        log.error("方法名:{}",methodName);
        log.error("方法参数:{}",Arrays.toString(joinPoint.getArgs()));
        log.error("方法返回值:{}",obj.toString());
        return obj;
    }
}

熟悉配置类

javascript 复制代码
package com.ming.log.module.config;

import org.springframework.boot.context.properties.ConfigurationProperties;

import javax.annotation.PostConstruct;

//让配置文件中的属性根据前缀来注入对应的属性
@ConfigurationProperties(value ="custom.log")
public class CustomLogProperties {

    //日志服务名,会自动找配置文件中customLog.serviceName
    private String serviceName;

    public String getServiceName() {
        return serviceName;
    }

    public void setServiceName(String serviceName) {
        this.serviceName = serviceName;
    }

}

启用配置

javascript 复制代码
package com.ming.log.module.config;

import com.ming.log.module.aop.CustomLogAspect;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
//用于显式地启用对@ConfigurationProperties注解类的支持。当你在你的应用中定义了配置属性类
//(即使用@ConfigurationProperties注解的类),你可以使用@EnableConfigurationProperties注解来告诉
//Spring Boot自动加载并绑定配置文件(如application.properties或application.yml)中的属性到这些类的字段上。
@EnableConfigurationProperties(CustomLogProperties.class)
public class CustomLogAutoConfiguration {

    @Bean
    public CustomLogAspect customLogAspect(CustomLogProperties customLogProperties){
        return new CustomLogAspect(customLogProperties);
    }

}

在resources下创建一个META-INF文件夹,然后在创建一个文件:spring.factories文件加入启用配置类的路径,springboot2.7之后有所不同,但是也兼容之前的版本写法

打包上传到maven私服(没搭建的直接install安装到本地maven仓库也可)

在别的工程引入,能这样看到基本就成功了

直接在方法上加@CustomLogAnnotation注解测试一下

到此为止已经成功,想做得好再好点的可以再把日志starter做成动态可插拔

相关推荐
bjzhang7540 分钟前
SpringBoot开发—— SpringBoot中如何实现 HTTP 请求的线程隔离
spring boot·线程隔离
Be_Somebody1 小时前
IoC究竟是什么?——IoC的基础分析
java·spring boot·spring·spring入门
潜洋1 小时前
Sping Boot教程之五十四:Spring Boot Kafka 生产者示例
java·spring boot·后端·kafka
怪只怪满眼尽是人间烟火1 小时前
Spring Boot集成RocketMQ
spring boot·rocketmq·java-rocketmq
李长渊哦1 小时前
Spring Boot 动态表操作服务实现
java·spring boot·后端
小学鸡!7 小时前
spring boot发送邮箱,java实现邮箱发送(邮件带附件)3中方式【保姆级教程一,代码直接用】
java·spring boot
loveLifeLoveCoding8 小时前
springboot 默认的 mysql 驱动版本
java·spring boot·mysql
Wonder-King9 小时前
springboot+vue使用easyExcel实现导出功能
vue.js·spring boot·后端
baozhengw10 小时前
SpringBoot项目实战(41)--Beetl网页使用自定义函数获取新闻列表
java·前端·spring boot