Spring Boot 核心配置与扩展实战:配置加载、IOC 管理、拦截器应用

在 Spring Boot 开发过程中,配置管理、IOC 容器使用、功能扩展(如拦截器)是高频核心知识点。本文结合实战案例,梳理配置加载优先级、Bean 注入技巧、拦截器开发等关键内容,理清底层逻辑,规避常见坑点。

一、Spring Boot 配置加载优先级与核心配置

1. 配置文件加载顺序

Spring Boot 支持 application.yml、application.yaml、application.properties 三种核心配置文件格式,同时支持通过 VM options、Program arguments 动态传参,后加载的配置会覆盖前序配置(如端口号)

加载优先级(由低到高):
application.properties
application.yaml/application.yml
VM options(JVM 启动参数,如 -Dserver.port=9001)
Program arguments(程序运行参数,如 --server.port=9002)

搭建集群时,可通过 VM options + Program arguments 组合动态指定不同节点的端口 / 数据库配置,无需修改配置文件。

2. 核心配置示例(application.properties)

以下是开发中常用的配置项,包含项目、数据库、端口、日志等关键配置:

# 项目名称
spring.application.name=boot-demo-2
# 数据库连接配置
spring.datasource.url=jdbc:mysql://localhost:3306/employee?useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# 服务器端口
server.port=8000
# 关闭 Thymeleaf 缓存
spring.thymeleaf.cache=false
# 日志级别:打印 Mapper 层 SQL 语句(调试 SQL 必备)
logging.level.cn.wolfcode.mapper=debug
# 自定义配置(可通过 @Value 读取)
user.name1234=Ehsan
user.password1234=333

注意:自定义配置无需加引号(如 user.name1234="Ehsan" ×),Spring 会自动识别字符串类型,加引号会导致读取的值包含引号,引发业务异常。

二、IOC 容器管理 Bean:自定义 Bean 注入与获取

Spring 核心是 IOC(控制反转),我们可通过配置类将自定义对象注入 IOC 容器,再通过注解获取,避免手动 new 对象,实现对象统一管理。

1. 自定义 Bean 注入(配置类方式)

创建配置类 → 读取自定义配置 → 注入 Bean 到 IOC。

第一步:编写配置类(BeanConfig.java)


//配置类:@Configuration 
@Configuration
public class BeanConfig {
    // @Value 读取配置文件中的自定义属性)
    @Value("${user.name1234}")
    private String name;

    @Value("${user.password1234}")
    private String password;

    /**
     * @Bean 注解:将方法返回值注入 IOC 容器,默认 Bean 名称为方法名(如 user1)
     * User 类需满足:有 name/password 属性 + getter/setter + 构造器 + toString
     */
    @Bean
    public User user1() {
        return new User(name, password);
    }
	
    @Bean
    public User user2() {
        return new User(name, password);
    }
}

2. 从 IOC 容器获取 Bean(三种常用方式)

当 IOC 中有多个同类型 Bean(如上例 user1、user2),需注意注入规则:

注解组合 匹配规则 适用场景
@Autowired 类型优先,名称次之 同类型 Bean 唯一时
@Resource 名称优先,类型次之 需按名称匹配 Bean 时
@Autowired + @Qualifier 指定 Bean 名称匹配 同类型多个 Bean 时(推荐)
@SpringBootTest
public class BeanTest {

    // 方式1:@Autowired 类型优先(同类型多个 Bean 会报错)
    // @Autowired
    // private User user;

    // 方式2:@Resource 名称优先(匹配 Bean 名称 user1)
    // @Resource
    // private User user1;

    // 方式3:@Autowired + @Qualifier 指定名称
    @Autowired
    @Qualifier("user2")
    private User user;

    @Test
    void testBean() {
        System.out.println(user);
    // 输出:User{name='Ehsan', password='333'}
    }
}

三、Mapper 接口简化配置:@MapperScan 替代单个 @Mapper

在 MyBatis 开发中,传统方式需在每个 Mapper 接口上添加 @Mapper 注解,当 Mapper 数量较多时,操作繁琐且易遗漏。

优化方案:主类添加 @MapperScan

在 Spring Boot 启动类上添加 @MapperScan,指定 Mapper 接口所在包路径,即可批量扫描所有 Mapper 接口,替代单个 @Mapper:

@SpringBootApplication
// 扫描指定包下的所有 Mapper 接口
@MapperScan(basePackages = "cn.wolfcode.mapper")
public class BootDemo2Application {
    public static void main(String[] args) {
        SpringApplication.run(BootDemo2Application.class, args);
    }
}

注意:basePackages 需填写 Mapper 接口的实际包路径。

四、Spring Boot 拦截器开发:请求耗时统计与功能扩展

拦截器(HandlerInterceptor)可拦截 Controller 请求,实现前置校验、后置处理等功能,是 Spring MVC 核心扩展点。

1. 自定义拦截器(统计接口耗时)

创建 TimeIntercept.java,实现 HandlerInterceptor 接口,重写前置 / 后置方法:


/**
 * 自定义拦截器:统计 Controller 接口执行耗时
 */
public class TimeIntercept implements HandlerInterceptor {

    /**
     * 前置拦截器:请求到达 Controller 前执行
     * 返回 true:放行;返回 false:拦截请求
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 记录请求开始时间,存入 request 域
        long startTime = new Date().getTime();
        request.setAttribute("startTime", startTime);
        System.out.println("前置拦截器执行:记录请求开始时间");
        return true;
    }

    /**
     * 后置拦截器:Controller 方法执行完成后、视图渲染前执行
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        // 获取前置拦截器存入的开始时间
        Long startTime = (Long) request.getAttribute("startTime");
        long endTime = new Date().getTime();
        // 计算并打印接口耗时
        System.out.println(request.getRequestURI() + " 接口耗时:" + (endTime - startTime) + "ms");
    }
}

2. 注册拦截器(保证 IOC 容器中对象唯一)

创建 WebConfiguration.java,实现 WebMvcConfigurer 接口,将拦截器注册到 Spring 容器:

/**
 * Web 配置类:注册拦截器
 */
@Configuration
public class WebConfiguration implements WebMvcConfigurer {

    // 1. 将拦截器注入 IOC 容器(保证对象唯一)
    @Bean
    public TimeIntercept timeIntercept() {
        return new TimeIntercept();
    }

    // 2. 获取注入 IOC 中的拦截器对象
    @Autowired
    private TimeIntercept timeIntercept;

    /**
     * 注册拦截器:指定拦截路径
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // /**:拦截所有请求(可根据业务指定路径)
        registry.addInterceptor(timeIntercept).addPathPatterns("/**");
    }
}

3. 解决循环依赖

若拦截器注入时出现循环依赖异常,在 application.properties 中添加配置:

# 允许循环依赖
spring.main.allow-circular-references=true

4. 拦截器典型应用场景

  • 前置拦截器(preHandle):用户登录授权、请求参数校验、敏感词过滤(如检测骂人内容)、接口限流等;
  • 后置拦截器(postHandle):数据脱敏(如隐藏手机号 / 身份证号)、日志记录、视图数据修改等;
  • afterCompletion(接口完成后执行):资源释放、异常统一处理等。

五、核心总结

  1. 配置加载:application.properties/yaml 是基础,VM options/Program arguments 动态配置优先级更高,集群场景常用;
  2. Bean 管理:@Configuration + @Bean 注入自定义对象,多同类型 Bean 用 @Autowired + @Qualifier 指定名称获取;
  3. Mapper 简化:@MapperScan 批量扫描 Mapper 接口,替代单个 @Mapper,提升开发效率;
  4. 拦截器开发:自定义拦截器需实现 HandlerInterceptor,并通过 WebMvcConfigurer 注册,可实现请求拦截、耗时统计、权限校验等核心功能。

通过以上实战配置,可大幅简化 Spring Boot 开发流程,规避常见坑点,同时掌握 IOC、拦截器等核心机制,为复杂业务开发打下基础。

posted @ 2026-01-30 19:26  Jennifer_F  阅读(5)  评论(0)    收藏  举报