前言

在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其它可拓展的用法

  1. 健康检查与依赖服务验证
  2.  配置验证与参数校验

  3. 数据初始化与种子数据加载

  4. 定时任务与后台服务启动

  5.  服务注册与发现

  6. ...................................

 4. 总结

这三个开发利器能够显著提升Spring Boot开发体验:

  1. SQL日志拦截器 - 让SQL调试变得简单直观
  2. 自定义Banner - 让应用启动更有仪式感,信息一目了然
  3. 启动监听器 - 让应用启动后自动执行初始化操作

这些工具不仅提高了开发效率,也让应用更加专业和易维护。在实际项目中,可以根据具体需求进行定制和扩展。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐