Spring Boot - Starter 机制

Spring Boot 核心 —— Starter 机制

1. 核心理论:什么是 Starter?

Starter,即“启动器”,是 Spring Boot 提供的一系列“一站式”依赖描述符。它本身通常不包含代码,主要是一个 Maven POM 文件,但它将构建特定类型应用所需的所有依赖都打包在了一起,并内置了默认的、经过测试的、兼容的版本。

  • 核心思想: 简化依赖管理。开发者不再需要自己去寻找和管理大量的、可能存在版本冲突的依赖,只需要引入一个对应的 Starter,就能获得所需的一切。

  • 生活比喻:

    • 没有 Starter: 你想自己组装一台电脑。你需要自己去研究 CPU、主板、内存条、显卡、电源等所有配件的型号,并确保它们之间互相兼容。这个过程非常复杂,且容易出错。
    • 有 Starter: 你去品牌电脑店,直接买一个“电竞主机”套装 (spring-boot-starter-web) 或者“商务办公”套装 (spring-boot-starter-data-jpa)。这个套装里已经为你搭配好了所有兼容的、性能最佳的配件,你只需要把它抱回家,插上电就能用。

2. 深度剖析:Starter 与自动配置的关系

Starter 和自动配置是相辅相成的,它们共同构成了 Spring Boot 的核心魔法。

  • Starter: 负责“引入依赖”。它把所有需要的“积木”(jar 包)都帮你搬到项目里。
  • 自动配置: 负责“拼装积木”。它看到项目里有了这些“积木”,就按照预设的“图纸”(@ConditionalOnClass 等条件),自动把它们组装起来。

工作流程:

  1. 你在 pom.xml 中引入 spring-boot-starter-web
  2. Maven 根据这个 Starter,自动下载了 spring-webmvc, spring-web, tomcat-embed, jackson-databind 等一系列依赖。
  3. Spring Boot 应用启动时,@EnableAutoConfiguration 开始工作。
  4. WebMvcAutoConfiguration 这个自动配置类,通过 @ConditionalOnClass 检测到 Servlet, DispatcherServlet 等类存在于类路径下
  5. 条件满足,WebMvcAutoConfiguration 生效,自动为你配置 DispatcherServlet 等所有 Spring MVC 相关的 Bean。

3. 如何自定义一个 Starter?

理解 Starter 最好的方式,就是亲手做一个。自定义一个 Starter 通常遵循“三步走”的规范。

假设我们要创建一个 zhaowumian-spring-boot-starter,它能自动配置一个 GreetingService,并允许用户在 application.yml 中配置问候语。

第一步:创建 ...-spring-boot-autoconfigure 模块

这个模块负责编写自动配置的逻辑。

  1. 创建配置属性类 (GreetingProperties.java)

    @ConfigurationProperties(prefix = "greeting")
    public class GreetingProperties {
        private String message = "Hello"; // 默认值
        // Getters and Setters
    }
    
  2. 创建业务服务类 (GreetingService.java)

    public class GreetingService {
        private GreetingProperties properties;
    
        public GreetingService(GreetingProperties properties) {
            this.properties = properties;
        }
    
        public String greet() {
            return properties.getMessage() + ", World!";
        }
    }
    
  3. 创建自动配置类 (GreetingAutoConfiguration.java)

    @Configuration
    @EnableConfigurationProperties(GreetingProperties.class) // 启用配置属性类
    @ConditionalOnClass(GreetingService.class) // 条件:当GreetingService类存在时
    @ConditionalOnProperty(prefix = "greeting", name = "enabled", havingValue = "true", matchIfMissing = true) // 条件:当配置greeting.enabled=true时,或没有配置时
    public class GreetingAutoConfiguration {
    
        @Bean
        @ConditionalOnMissingBean // 条件:当容器中没有GreetingService的Bean时
        public GreetingService greetingService(GreetingProperties properties) {
            return new GreetingService(properties);
        }
    }
    
  4. 创建 spring.factories 文件
    src/main/resources/META-INF/ 目录下创建 spring.factories 文件,内容如下:

    org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
      com.study.starter.GreetingAutoConfiguration
    

    这个文件就是用来告诉 Spring Boot:“嘿,我这里有一个自动配置类,你启动时记得加载它!”

第二步:创建 ...-spring-boot-starter 模块

这个模块是“”的,它不包含任何代码,只有一个 pom.xml 文件,它的唯一作用就是管理依赖

<project ...>
    <artifactId>zhaowumian-spring-boot-starter</artifactId>

    <dependencies>
        <!-- 这个 Starter 会自动传递对 autoconfigure 模块的依赖 -->
        <dependency>
            <groupId>com.study</groupId>
            <artifactId>zhaowumian-spring-boot-autoconfigure</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>
</project>

第三步:在其他项目中使用我们的 Starter

  1. 在你的 Spring Boot 项目的 pom.xml 中,引入我们刚刚创建的 Starter:

    <dependency>
        <groupId>com.study</groupId>
        <artifactId>zhaowumian-spring-boot-starter</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
    
  2. application.yml 中进行配置:

greeting:
message: "Hi"
```

  1. 在代码中直接注入并使用 GreetingService
    @RestController
    public class MyController {
        @Autowired
        private GreetingService greetingService;
    
        @GetMapping("/greet")
        public String greet() {
            return greetingService.greet(); // 输出 "Hi, World!"
        }
    }
    

通过这三步,我们就实现了一个功能完整的自定义 Starter。它遵循了 Spring Boot 的所有核心原则:依赖管理、自动配置、按需加载和用户优先。


4. Q&A

为什么要把 autoconfigurestarter 分成两个模块?

这是 Spring Boot 官方推荐的最佳实践,核心是为了关注点分离 (Separation of Concerns)

  • autoconfigure 模块: 只包含自动配置的核心逻辑代码,不依赖任何具体的项目。
  • starter 模块: 不包含任何代码,它是一个纯粹的“依赖描述符”,负责将 autoconfigure 模块以及其他可能需要的第三方库(如 spring-web 等)打包在一起。

这样做的好处是,用户只需要引入一个干净的 starter 依赖,就能获得所有功能,而无需关心底层的自动配置细节和复杂的依赖关系。

@ConditionalOnMissingBean 在这里起到了什么关键作用?

它起到了“用户优先”的关键作用,是 Spring Boot “约定优于配置”思想的重要体现。

  • 作用: 它允许用户通过在自己的项目里定义一个同类型的 Bean(比如自己写一个 GreetingService 并加上 @Bean 注解),来覆盖我们 Starter 中提供的默认 Bean。
  • 效果: 当 Spring 容器中已经存在一个 GreetingService 类型的 Bean 时,@ConditionalOnMissingBean 的条件不满足,我们 GreetingAutoConfiguration 中的那个 @Bean 方法就不会被执行。这使得我们的 Starter 在提供便利的同时,又不失灵活性,用户可以随时接管配置。
posted @ 2026-01-21 16:22  我是刘瘦瘦  阅读(3)  评论(0)    收藏  举报