在电商系统的开发中,config 配置模块不仅是 Spring Boot 应用启动的基础支撑部分,更承担着系统稳定性、性能优化和开发便利的重任。本篇博客将深入分析商城项目中 config 层的实现内容,涵盖异常处理、七牛云文件上传配置、MyBatisPlus 拓展、Redis 缓存配置四大核心方向,逐段解析每一项功能的设计初衷、关键逻辑与优化实践。
一、统一异常处理机制 DefaultExceptionHandlerConfig
在一个后端服务日常运行中,出现异常并不可怕,可怕的是异常信息无法规范返回、错误码混乱、日志无法定位。为此,我们设计了统一的异常处理入口:DefaultExceptionHandlerConfig。
1. 核心注解
@RestControllerAdvice
@Controller
@Slf4j
通过 @RestControllerAdvice 拦截全局 Controller 层抛出的异常,并使用 @ExceptionHandler 统一封装处理。
2. 参数校验异常处理
@ExceptionHandler({ MethodArgumentNotValidException.class, BindException.class })
当接口请求体中对象属性不符合 @NotBlank、@NotNull 等 JSR-303 校验注解时,将触发该分支处理逻辑:
-
提取错误字段信息
-
拼接成如 field:错误原因 的列表
-
返回统一封装的 ServerResponseEntity.fail(...) 响应对象
实践中用户提交表单出错的反馈非常关键,配合前端可实现自动校验高亮展示。
3. 自定义业务异常封装
系统内部通过抛出 YamiShopBindException(继承自 RuntimeException)主动中断执行流,并返回带错误码和信息的 ServerResponseEntity。
@ExceptionHandler(YamiShopBindException.class)
这种设计保证了业务校验失败(如“订单已取消不可支付”、“商品已下架”等)与系统异常(500错误)完全解耦,提高可维护性与用户体验。
4. 兜底异常处理
@ExceptionHandler(Exception.class)
任何未被显式处理的异常,均会落入此方法并输出标准日志,防止异常堆栈被吞。对于404资源找不到的 NoResourceFoundException,也进行了特殊处理。
二、七牛云文件上传配置 FileUploadConfig
项目使用七牛云作为图片、视频、文件存储服务端,这部分配置职责是:
-
通过 YAML 配置项注入七牛参数
-
初始化 SDK 所需的核心组件:Zone、UploadManager、Auth、BucketManager
1. 自动装配七牛配置参数
@Autowired
private Qiniu qiniu;
配置类 Qiniu(通常通过 @ConfigurationProperties 读取配置文件)包含:
-
accessKey / secretKey
-
bucketName
-
上传区域(华北、华南、新加坡等)
2. 构造上传配置实例
@Bean
public UploadManager uploadManager() {
return new UploadManager(qiniuConfig());
}
上传配置的核心在于根据 zone 初始化 com.qiniu.storage.Configuration,配合 UploadManager 即可执行上传请求。
3. 授权与空间管理
@Bean
public Auth auth() {
return Auth.create(qiniu.getAccessKey(), qiniu.getSecretKey());
}
@Bean
public BucketManager bucketManager() {
return new BucketManager(auth(), qiniuConfig());
}
这两个组件分别用于生成上传凭证、操作空间(如查询文件、删除等),是 SDK 功能全量调用的基础。
三、MyBatisPlus 配置扩展 MybatisPlusConfig
MyBatis-Plus 是目前主流的 ORM 框架,它在 MyBatis 的基础上封装了分页插件、乐观锁插件、SQL注入器等功能。
1. 启动 Mapper 扫描
@MapperScan({"com.yami.shop.**.dao"})
保证所有 DAO 层接口自动注册为 Mapper。
2. 分页与乐观锁插件集成
@Bean
public MybatisPlusInterceptor optimisticLockerInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return interceptor;
}
-
分页插件支持 PageHelper 风格的分页
-
乐观锁插件配合 @Version 字段控制并发修改冲突,保障数据一致性
3. SQL 注入器支持逻辑删除
@Bean
public ISqlInjector sqlInjector() {
return new DefaultSqlInjector();
}
这为后续逻辑删除提供扩展基础(例如调用 deleteById 实际执行 UPDATE ... SET deleted = 1)
四、Redis 缓存体系配置 RedisCacheConfig
Redis 在项目中不仅承担着缓存功能,更承载了高性能的临时数据、分布式事务、限流与推荐模块缓存等多项任务。
1. 缓存策略设置
public CacheManager cacheManager(...) { ... }
-
默认所有 key 的缓存时间为 3600 秒
-
对于特定 key,例如 product,设置了独立 TTL(1800 秒)
这种细粒度配置保证了不同业务场景下缓存时效性需求不同的合理性。
2. RedisTemplate 初始化
@Bean
public RedisTemplate<String, Object> redisTemplate(...)
-
key、hashKey 使用 String 序列化
-
value、hashValue 使用自定义 RedisSerializer<Object>
3. 高级序列化支持(GenericJackson2JsonRedisSerializer)
@Bean
public RedisSerializer<Object> redisSerializer()
这段代码体现了对 Java 时间类(LocalDateTime、Instant 等)和泛型类型的支持:
-
注册 JSR310 时间模块:JavaTimeModule
-
启用默认类型信息:@class
-
关闭反序列化失败抛异常(提升兼容性)
-
注册 null 序列化处理器
这种序列化方式兼容性极强,可用于存储复杂的 POJO、嵌套集合与动态类型。
4. String 类型 RedisTemplate
@Bean
public StringRedisTemplate stringRedisTemplate(...)
作为补充,用于处理纯文本或键值类型逻辑,常用于:
-
业务限流器
-
布隆过滤器
-
简单缓存标记位
五、总结与个人体会
config 模块虽然不直接参与业务逻辑,却构成了整个系统运行的“底盘”与“润滑油”。本文介绍的四大配置模块从异常保障、文件上传、ORM 拓展再到缓存系统,都是一个生产级电商项目必不可少的技术底座。
通过分析可见,这一模块的设计具备如下特征:
-
稳定性强:统一异常兜底、兜住风险
-
兼容性强:Redis序列化对时间、泛型、null 做了完善处理
-
可拓展性高:MyBatis插件支持逻辑删除、分页、乐观锁三合一
-
与业务无缝集成:如七牛配置通过 Bean 注入实现业务上传服务无感依赖
config 不是“配一下就忘”的代码,而是系统“生命线”的守护者。建议每一位开发者在阅读此类配置时,不止停留于“能用”,更要理解“为什么这么配”“可不可以优化”——唯有这样,才能从架构的角度真正掌控系统质量。