Spring Boot 开发利器:SQL日志拦截器、自定义Banner和启动监听器
·
前言
在Spring Boot开发中,我们经常需要一些工具来提升开发效率和调试体验。本文将分享三个实用的开发利器:SQL日志拦截器、自定义Banner和启动监听器。这些工具能够帮助开发者更好地监控应用状态、调试SQL语句,并提供更好的开发体验
1. SQL日志拦截器 - 让SQL语句无处遁形
1.1 为什么需要SQL日志拦截器?
在开发过程中,我们经常需要查看MyBatis执行的SQL语句,以便调试和优化。虽然MyBatis提供了日志功能,但默认的日志格式不够友好,参数值也没有很好地展示。我们的SQL日志拦截器能够:
- 显示完整的SQL语句(参数已替换)
- ⏱️ 记录SQL执行时间
- 🎨 格式化SQL语句,提高可读性
- 异常时提供详细的错误信息
1.2 核心实现
@Slf4j
@Intercepts({
@Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class}),
@Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class})
})
public class SqlLogInterceptor implements Interceptor {
@Override
public Object intercept(Invocation invocation) throws Throwable {
MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
Object parameter = invocation.getArgs()[1];
// 获取SQL语句
BoundSql boundSql = mappedStatement.getBoundSql(parameter);
String sql = boundSql.getSql();
// 获取参数并替换占位符
String finalSql = getSql(sql, parameter, boundSql.getParameterMappings(), mappedStatement.getConfiguration());
// 格式化SQL语句
String formattedSql = formatSql(finalSql);
// 记录执行开始时间
long startTime = System.currentTimeMillis();
try {
// 打印SQL执行信息
log.info("=== SQL执行监听 ===");
log.info("执行方法: {}", invocation.getMethod().getName());
log.info("SQL语句:\n{}", formattedSql);
log.info("参数: {}", parameter);
log.info("==================");
// 执行原始方法
Object result = invocation.proceed();
// 计算执行时间
long costTime = System.currentTimeMillis() - startTime;
log.info("=== SQL执行完成 ===");
log.info("执行时间: {}ms", costTime);
log.info("==================");
return result;
} catch (Exception e) {
long costTime = System.currentTimeMillis() - startTime;
log.error("=== SQL执行异常 ===");
log.error("执行时间: {}ms", costTime);
log.error("异常信息: {}", e.getMessage(), e);
log.error("==================");
throw e;
}
}
}
1.3 配置使用
package com.jair.common.config;
import com.jair.common.Inteceptor.SqlLogInterceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import javax.annotation.PostConstruct;
import java.util.List;
/**
* SQL日志配置类
* 用于注册SQL监听拦截器
*
* @author jair
* @since 2025-01-01
*/
@Configuration
public class SqlLogConfig {
@Autowired
private List<SqlSessionFactory> sqlSessionFactoryList;
/**
* 在所有SqlSessionFactory初始化完成后,添加SQL日志拦截器
*/
@PostConstruct
public void addInterceptor() {
// 只对第一个SqlSessionFactory添加拦截器,避免重复注册
if (!sqlSessionFactoryList.isEmpty()) {
// 手动创建拦截器实例,避免重复
SqlLogInterceptor sqlLogInterceptor = new SqlLogInterceptor();
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryList.get(0);
sqlSessionFactory.getConfiguration().addInterceptor(sqlLogInterceptor);
}
}
}
1.4 效果展示
=== SQL执行监听 ===
执行方法: query
SQL语句:
SELECT
id, userAccount, userName, userRole, createTime
FROM
user
WHERE
userAccount = 'test123'
AND isDelete = 0
参数: {userAccount=test123}
==================
=== SQL执行完成 ===
执行时间: 15ms
==================
2. 自定义Banner - 让启动更有仪式感
2.1 Banner的作用
Banner是Spring Boot启动时显示的艺术字,它不仅能让应用启动更有仪式感,还能帮助开发者快速识别应用版本和环境信息。
2.2 自定义Banner实现(佛祖保佑)
在src/main/resources/banner.txt中定义: PS:内容可以自定义
${AnsiColor.BRIGHT_YELLOW}// _ooOoo_
// o8888888o
// 88" . "88
// (| -_- |)
// O\ = /O
// ____/`---'\____
// . ' \\| |// `.
// / \\||| : |||// \
// / _||||| -:- |||||- \
// | | \\\ - /// | |
// | \_| ''\---/'' | |
// \ .-\__ `-` ___/-. /
// ___`. .' /--.--\ `. . __
// ."" '< `.___\_<|>_/___.' >'"".
// | | : `- \`.;`\ _ /`;.`/ - ` : | |
// \ \ `-. \_ __\ /__ _/ .-` / /
// ======`-.____`-.___\_____/___.-`____.-'======
// `=---='
//
// .............................................
${AnsiColor.BRIGHT_RED} 佛祖保佑 永无BUG
${AnsiColor.BRIGHT_CYAN} 佛曰:
${AnsiColor.BRIGHT_GREEN} 写字楼里写字间,写字间里程序员;
// 程序人员写程序,又拿程序换酒钱。
// 酒醒只在网上坐,酒醉还来网下眠;
// 酒醉酒醒日复日,网上网下年复年。
// 但愿老死电脑间,不愿鞠躬老板前;
// 奔驰宝马贵者趣,公交自行程序员。
// 别人笑我忒疯癫,我笑自己命太贱;
// 不见满街漂亮妹,哪个归得程序员?
${AnsiColor.DEFAULT}
${AnsiColor.BRIGHT_BLUE}${application.title} ${application.version}
${AnsiColor.BRIGHT_MAGENTA}Spring Boot ${spring-boot.version}
${AnsiColor.BRIGHT_CYAN}Java ${java.version}
${AnsiColor.BRIGHT_GREEN}Profile: ${spring.profiles.active:default}
${AnsiColor.BRIGHT_YELLOW}Port: ${server.port:8080}
${AnsiColor.BRIGHT_RED}Context: ${server.servlet.context-path:/}
${AnsiColor.BRIGHT_WHITE}OS: ${os.name} ${os.version}
2.3 Banner配置
在application.yml中可以配置Banner相关属性: PS:Spring默认识别resource下面得banner.txt文件也可以不配置,当然也可以自定义配置
spring:
banner:
charset: UTF-8
location: classpath:banner.txt
# 是否启用Banner
enabled: true
2.4 效果展示
启动时会显示彩色的Banner,包含应用信息、版本号、端口等关键信息,让开发者一目了然地了解应用状态。
🚀 3. 启动监听器 - 应用启动后的智能助手
3.1 启动监听器的作用
应用启动完成后,我们经常需要执行一些初始化操作,比如:
- 打印应用访问地址
- 缓存预热
- 📝 记录启动日志
- 🔧 初始化配置
3.2 核心实现(缓存预热)
@Slf4j
@Component
@RequiredArgsConstructor
public class ApplicationStartupListener {
/**
* 应用启动完成后执行
*
* @param event 应用就绪事件
*/
@EventListener(ApplicationReadyEvent.class)
public void onApplicationReady(ApplicationReadyEvent event) {
log.info("应用启动完成,开始执行初始化操作");
// 打印应用访问信息
System.out.println("--------------------------------");
System.out.println("基本端口信息: http://localhost:8080/api");
System.out.println("--------------------------------");
System.out.println("Knife4j 地址: http://localhost:8080/api/doc.html");
System.out.println("--------------------------------");
// 可以在这里添加缓存预热逻辑
// cacheWarmUp();
// 可以在这里添加其他初始化操作
// initOtherServices();
}
/**
* 缓存预热示例
*/
private void cacheWarmUp() {
log.info("开始缓存预热...");
// 预热常用数据到Redis
// redisTemplate.opsForValue().set("cache:hot:data", "value", 1, TimeUnit.HOURS);
log.info("缓存预热完成");
}
}
3.3其它可拓展的用法
- 健康检查与依赖服务验证
-
配置验证与参数校验
-
数据初始化与种子数据加载
-
定时任务与后台服务启动
-
服务注册与发现
-
...................................
4. 总结
这三个开发利器能够显著提升Spring Boot开发体验:
- SQL日志拦截器 - 让SQL调试变得简单直观
- 自定义Banner - 让应用启动更有仪式感,信息一目了然
- 启动监听器 - 让应用启动后自动执行初始化操作
这些工具不仅提高了开发效率,也让应用更加专业和易维护。在实际项目中,可以根据具体需求进行定制和扩展。
更多推荐


所有评论(0)