系统日志优化---自定义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做成动态可插拔

相关推荐
程序猿小蒜15 分钟前
基于Spring Boot的宠物领养系统的设计与实现
java·前端·spring boot·后端·spring·宠物
皮皮林55123 分钟前
SpringBoot + Spring AI 玩转智能应用开发
spring boot
w***48134 分钟前
Springboot项目本地连接并操作MySQL数据库
数据库·spring boot·mysql
90后小陈老师39 分钟前
用户管理系统 07 项目前端初始化 | 新手实战 | 期末实训 | Java+SpringBoot+Vue
java·前端·spring boot
k***825142 分钟前
springboot整合libreoffice(两种方式,使用本地和远程的libreoffice);docker中同时部署应用和libreoffice
spring boot·后端·docker
l***46681 小时前
springboot使用redis
spring boot·redis·后端
Coder-coco1 小时前
点餐|智能点餐系统|基于java+ Springboot的动端的点餐系统小程序(源码+数据库+文档)
java·vue.js·spring boot·小程序·论文·毕设·电子点餐系统
程序员小单1 小时前
WebSocket 与 Spring Boot 整合实践
spring boot·websocket·网络协议
q***96582 小时前
深入解析Spring Boot中的@ConfigurationProperties注解
java·spring boot·后端
发现你走远了2 小时前
2025 idea 指定配置环境运行springboot 设置active和env启动端口,多端口启动 (保姆级图文)
java·spring boot·intellij-idea