强大!Spring Boot 3.3 构建通用库,彻底告别重复代码!
在现代软件开发中,代码的复用性是衡量项目架构和设计优劣的重要指标之一。随着项目的逐渐扩展和功能的增多,开发者往往会面临同样的挑战:如何减少冗余代码并提高代码的复用效率。尤其在大规模的企业级应用开发中,开发不同模块时,经常会遇到重复使用相同功能和逻辑的场景。如果每次都重复编写这些功能,不仅增加了开发工作量,也为后期的维护带来了额外的复杂度。
因此,构建一个通用库(Common Library)变得尤为重要。通用库可以作为公共组件,封装重复的业务逻辑、工具类、配置项以及通用的服务功能,在不同项目中复用,极大地提升代码复用性和开发效率。通过 Spring Boot 3.3 提供的强大功能,结合 Spring 框架本身的配置能力以及 Spring Boot 的模块化扩展机制,我们可以轻松实现一个灵活、可扩展的通用库,使其能够应用到不同的项目中。
在本文中,我们将结合 Spring Boot 3.3,深入探讨如何设计和实现一个通用库,并通过实际的功能模块构建,展示如何在项目中高效复用代码。我们将通过一个典型的示例——日志配置管理库,来展示如何封装通用功能,并结合代码示例,深入讲解每个步骤的实现。
运行效果:
若想获取项目完整代码以及其他文章的项目源码,且在代码编写时遇到问题需要咨询交流,欢迎加入下方的知识星球。
典型示例:构建通用日志配置管理库
在实际项目中,日志记录是非常重要的功能之一,不同项目往往需要不同的日志格式、级别和输出位置。为了避免在每个项目中重复配置日志功能,我们可以通过构建一个通用的日志配置管理库来解决这个问题。通过 @ConfigurationProperties
读取配置文件中的日志参数,结合 Lombok 简化配置类的开发,最后将这些配置应用到日志系统中,提供统一的日志管理功能。
项目依赖配置(pom.xml)
首先,我们需要在项目的 pom.xml
文件中配置相关的依赖。我们使用 Spring Boot 的核心依赖,加入 Lombok
来简化 POJO(Plain Old Java Object)的开发,并使用 Thymeleaf 模板引擎来处理前端视图。
<?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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.3.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.icoderoad</groupId>
<artifactId>common-log-library</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>common-log-library</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<!-- Spring Boot 核心依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Boot Logging 依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</dependency>
<!-- Lombok 依赖 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<!-- Thymeleaf 模板引擎 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</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>
配置文件(application.yml)
接下来,我们定义通用日志配置参数,作为配置文件的一部分。在 application.yml
中,我们将日志相关的参数定义好,以便不同项目根据需求加载不同的配置。
logging:
log-level: DEBUG
log-path: /var/logs/application.log
log-pattern: "%d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg%n"
日志配置类
我们创建一个 LogProperties
类,通过 @ConfigurationProperties
注解将配置文件中的日志配置参数读取到 Java 类中。使用 Lombok 的 @Data
注解来简化代码。
package com.icoderoad.common.log.library.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Data
@Component
@ConfigurationProperties(prefix = "logging")
public class LogProperties {
private String logLevel;
private String logPath;
private String logPattern;
}
日志服务类
为了展示如何使用配置参数,我们创建一个 LogService
类,通过读取 LogProperties
中的配置来设置日志功能,并且将日志输出到指定的路径。为了实现 LogService
服务类的 setupLogging
方法,并将日志配置真正应用到系统中,我们可以使用 Spring Boot 内置的 Logger
机制与 Logback 或 Log4j2 日志框架进行集成。Spring Boot 默认使用 Logback 作为其日志系统,但也可以根据需要使用其他日志框架。下面将使用 Logback 作为例子,展示如何动态设置日志级别、日志格式以及输出路径。
具体实现步骤:
读取日志配置: 通过
LogProperties
类获取配置文件中的日志级别、格式以及日志路径。配置 Logback: 动态设置日志的输出级别、日志文件路径和日志格式。
应用日志配置到系统: 将这些配置应用到日志框架中,使其在运行时能够动态调整日志配置。
具体代码实现
LogService
服务类
package com.icoderoad.common.log.library.service;
import java.nio.charset.Charset;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.icoderoad.common.log.library.config.LogProperties;
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.FileAppender;
import ch.qos.logback.core.util.StatusPrinter;
@Service
public class LogService {
@Autowired
private LogProperties logProperties;
public void setupLogging() {
// 获取根日志记录器
Logger rootLogger = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
// 设置日志级别
rootLogger.setLevel(Level.toLevel(logProperties.getLogLevel(), Level.INFO));
// 创建文件追加器,指定日志输出路径
FileAppender<ILoggingEvent> fileAppender = new FileAppender<>();
fileAppender.setFile(logProperties.getLogPath());
// 创建日志格式的编码器
PatternLayoutEncoder encoder = new PatternLayoutEncoder();
encoder.setContext(rootLogger.getLoggerContext());
encoder.setCharset(Charset.forName("UTF-8"));
encoder.setPattern(logProperties.getLogPattern());
encoder.start();
// 将编码器绑定到文件追加器
fileAppender.setEncoder(encoder);
fileAppender.setContext(rootLogger.getLoggerContext());
fileAppender.start();
// 清除现有的附加器,添加新的文件追加器
rootLogger.detachAndStopAllAppenders();
rootLogger.addAppender(fileAppender);
// 打印当前日志系统的状态
StatusPrinter.print(rootLogger.getLoggerContext());
// 记录日志,验证是否成功应用配置
rootLogger.info("日志配置已成功应用到系统!");
}
}
详细功能实现解释:
获取日志级别并应用:
rootLogger.setLevel()
:根据LogProperties
中的日志级别配置动态设置日志的输出级别。如果配置中的日志级别无效,则默认使用INFO
级别。
配置日志输出位置(文件):
FileAppender<ILoggingEvent>
:定义日志输出的文件路径,日志将被写入logProperties.getLogPath()
指定的位置。detachAndStopAllAppenders()
:在重新配置日志时,先清除所有现有的附加器,确保只有一个文件追加器在运行。
设置日志格式:
PatternLayoutEncoder
:用来定义日志输出的格式,通过配置文件中的日志格式(logProperties.getLogPattern()
)来设置日志条目的布局格式。
动态应用日志配置:
StatusPrinter.print()
:用于打印当前的日志系统状态,便于调试和查看日志系统的运行情况。
日志示例:
rootLogger.info()
:在配置应用后输出一条日志,确认日志已经成功配置。
控制器层
在控制器层,我们可以通过一个 REST API 来展示日志配置是否成功。访问该 API 可以确认日志配置是否已经加载并生效。
package com.icoderoad.common.log.library.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import com.icoderoad.common.log.library.service.LogService;
@RestController
public class LogController {
@Autowired
private LogService logService;
@GetMapping("/setup-logging")
public String setupLogging() {
logService.setupLogging();
return "日志配置已成功应用";
}
}
前端部分
我们使用 Thymeleaf 模板引擎和 jQuery 结合 Bootstrap 来实现前端页面。在 templates/index.html
中创建一个简单的页面,当用户点击按钮时,发起 Ajax 请求,调用日志配置的 REST API。
在 src/main/resources/templates/index.html
文件中使用 Thymeleaf 模板显示配置信息:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>日志配置管理</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
<h1>日志配置管理</h1>
<button id="setupLogBtn" class="btn btn-primary">设置日志配置</button>
<div id="logInfo" class="mt-3"></div>
</div>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<script>
$(document).ready(function () {
$('#setupLogBtn').click(function () {
$.ajax({
url: '/setup-logging',
method: 'GET',
success: function (data) {
$('#logInfo').html('<div class="alert alert-success">' + data + '</div>');
},
error: function () {
$('#logInfo').html('<div class="alert alert-danger">日志配置失败</div>');
}
});
});
});
</script>
</body>
</html>
总结
在这篇文章中,我们深入讨论了如何在 Spring Boot 3.3 中构建一个通用日志配置管理库,通过使用 @ConfigurationProperties
动态加载配置文件,结合 Lombok 简化实体类的编写。构建通用库不仅提升了代码的复用性,还为后续的维护提供了便利。通过构建通用库,我们可以轻松管理项目中的日志配置,使不同项目可以共享相同的功能模块,减少了重复代码的编写。此外,结合 Thymeleaf 和 Bootstrap 实现前端的展示,进一步提高了用户的操作体验。
在实际开发中,通用库的使用场景非常广泛。我们可以将日志、异常处理、数据访问等功能模块封装为通用库,灵活应用到不同的项目中,显著提高开发效率和代码质量。