找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

3102

积分

0

好友

424

主题
发表于 2026-2-15 19:32:29 | 查看: 28| 回复: 0

Spring Boot 作为 Java 开发领域的核心框架,通过其“约定优于配置”的理念,极大地简化了应用的初始搭建与开发过程。其中,自动装配机制允许开发者通过简单的依赖引入,即可将复杂的 Bean 对象自动注入到 IoC 容器中,显著减少了样板代码,让开发者能更专注于业务逻辑的实现。本文将深入剖析这一机制的运作原理,并通过一个完整的示例,演示如何从零开始手写一个可复用的自定义 Starter 组件。

自动装配原理剖析

理解 Spring Boot 自动装配,首先需要了解 Java 的 SPI(Service Provider Interface)机制。其核心流程可以概括为以下几个关键步骤:

  1. 启动入口:Spring Boot 应用启动时,会扫描主类上的 @SpringBootApplication 复合注解。
  2. 核心注解@SpringBootApplication 注解内部包含了 @EnableAutoConfiguration 注解,这是激活自动配置功能的关键。
  3. 导入选择器@EnableAutoConfiguration 注解通过 @Import 导入了 AutoConfigurationImportSelector 类。该类的主要职责是执行 selectImports 方法。
  4. 加载配置selectImports 方法并非凭空创造配置,而是基于 SPI 机制,去项目 classpath 下所有 META-INF/spring.factories 文件中,查找 org.springframework.boot.autoconfigure.EnableAutoConfiguration 配置项对应的值。
  5. 注册 Bean:这些配置项的值是一个个自动配置类(标注了 @Configuration)的全限定名。Spring Boot 会加载这些配置类,并根据其中的条件注解(如 @ConditionalOnClass)判断是否生效。生效的配置类中定义的 @Bean 方法,其返回的对象就会被自动注册到 Spring IoC 容器中。

整个过程的“自动”之处在于,开发者无需显式地在自己的代码中使用 @Configuration@Bean 来声明这些组件,只需引入相应的 Starter 依赖,符合条件后便会自动完成装配。

为了更直观地理解,我们可以查看官方 Starter 的结构。例如,在项目的依赖库中打开 mybatis-spring-boot-autoconfigure-2.2.2.jar 包,其 META-INF 目录下就存在一个 spring.factories 文件,其核心内容通常如下所示:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
  org.mybatis.spring.boot.autoconfigure.MybatisLanguageDriverAutoConfiguration,\
  org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration

而官方提供的 Starter(如 spring-boot-starter-web),其自动配置类则直接定义在 spring-boot-autoconfigure-2.6.11.jar 包的 META-INF/spring.factories 文件中,其中定义了大量的 ApplicationContextInitializerApplicationListenerAutoConfigurationImportFilter 等,构成了完整的自动配置体系。

手写一个自定义 Starter 实战

理解了原理,我们通过一个简单的示例来实践如何创建一个自定义 Starter。我们将创建一个名为 “boy-starter” 的组件,它能够根据配置自动向容器中注入一个 Boy 对象。

第一步:创建 Starter 项目

首先,我们创建一个标准的 Maven 项目,注意,不需要 application.propertiesApplication 主启动类。项目的核心目录结构如下所示:

demo
├── .idea
├── src
│   ├── main
│   │   ├── java
│   │   │   └── com
│   │   │       └── sc
│   │   │           └── demo
│   │   │               ├── Boy.java
│   │   │               ├── BoyAutoConfiguration.java
│   │   │               └── BoyProperties.java
│   │   └── resources
│   │       └── META-INF
│   │           ├── additional-spring-configuration-metadata.json
│   │           └── spring.factories
│   └── test
└── .gitignore

第二步:定义核心业务类

我们创建一个简单的 Boy 类,它有一个 say() 方法。

/**
 * @author suncong
 */
public class Boy{
    public static Boy create(String name){
        return new Boy(name);
    }

    private String name;

    public Boy(String name){
        this.name = name;
    }

    public String getName(){
        return name;
    }

    public void setName(String name){
        this.name = name;
    }

    public String say(){
        return name+",Hello World!";
    }
}

第三步:创建自动配置类

这是 Starter 的核心,它决定了在什么条件下创建 Boy Bean。

/**
 * @author suncong
 */
@ConditionalOnClass(Boy.class) // 当类路径下存在 Boy 类时,此配置类才生效
@EnableConfigurationProperties(BoyProperties.class) // 启用配置属性类
@Configuration
@Data
@ComponentScan
public class BoyAutoConfiguration{

    /**
     * 将对象交给IOC管理
     * @param boyProperties
     * @return
     */
    @Bean
    Boy boy(BoyProperties boyProperties){
        return new Boy(boyProperties.getName());
    }

}

第四步:定义配置属性类

该类负责从使用方的配置文件中读取属性。

/**
 * @author suncong
 */
@ConfigurationProperties(prefix = "demo.boy")
public class BoyProperties{
    private String name;

    public String getName(){
        return name;
    }

    public void setName(String name){
        this.name = name;
    }
}

第五步:编写 META-INF 配置文件

这是实现自动装配的“钥匙”,必须正确创建。

  1. spring.factories (必须)
    src/main/resources/META-INF/ 下创建此文件,内容指定我们的自动配置类。

    org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
      com.sc.demo.BoyAutoConfiguration

    注意:路径和文件名必须完全正确,常见的错误有拼写为 META_INFspring.factoies

  2. additional-spring-configuration-metadata.json (可选)
    此文件用于为 IDE 提供配置项的元数据提示(如类型、描述、默认值),提升开发体验。

    {
      "properties": [
        {
          "name":  "demo.boy.name",
          "type": "java.lang.String",
          "description": "想跳舞的人",
          "defaultValue": "sc"
        }
      ]
    }

第六步:打包安装

在 IDE 的 Maven 工具窗口中,依次执行 cleaninstall 命令,将我们编写的 Starter 项目打包并安装到本地 Maven 仓库。成功执行后,其他本地项目就可以像引用其他依赖一样引用这个自定义 Starter 了。

第七步:测试使用 Starter

现在,我们新建一个普通的 Spring Boot 应用来测试这个 Starter。

  1. 添加依赖:在 pom.xml 中引入我们刚刚创建的 Starter。

    <dependency>
        <groupId>com.sc</groupId>
        <artifactId>demo</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
  2. 编写主应用:创建一个简单的 Web 控制器,并自动注入 Boy 对象。

    /**
     * @author SunCong
     */
    @RestController
    @SpringBootApplication
    public class Demo1Application{
        public static void main(String[] args){
            SpringApplication.run(Demo1Application.class, args);
        }
    
        @Autowired
        private com.sc.demo.Boy boy;
    
        @GetMapping("/say")
        public String say(){
            return boy.say();
        }
    }
  3. 配置文件:在 application.properties 中配置 Boy 的名称。

    server.port=8081
    demo.boy.name="scscsc"
  4. 启动与测试
    启动应用,控制台会输出标准的 Spring Boot 启动日志,包括 “Tomcat started on port(s): 8081 (http)” 等信息,表明应用启动成功。
    打开浏览器访问 localhost:8081/say,页面将显示:“scscsc, Hello World!”
    修改配置文件中的 demo.boy.name 值为 "shuaige" 并重启应用,再次访问,页面将显示:“shuaige, Hello World!”

至此,一个功能完整的自定义 Spring Boot Starter 就开发并验证成功了。

官方 Starter 与第三方 Starter 的区别

在日常开发中,我们可能会注意到两种命名风格的 Starter,例如:

  • spring-boot-starter-web (官方)
  • mybatis-spring-boot-starter (第三方)

它们的主要区别在于:

  1. 命名规范:官方的 Starter 通常遵循 spring-boot-starter-{功能模块} 的命名方式;而第三方 Starter 则通常使用 {模块名}-spring-boot-starter 的格式。
  2. 自动配置类的位置:这是最关键的技术区别。
    • 第三方 Starter(如 MyBatis)的自动配置类定义在其自身 JAR 包META-INF/spring.factories 文件中。
    • 官方提供的 Starter(如 Web、JPA 等)的自动配置类,是集中定义在 spring-boot-autoconfigure 这个独立 JAR 包META-INF/spring.factories 文件中的。这个文件里包含了 ApplicationContextInitializerApplicationListenerAutoConfigurationImportFilter 以及海量的 EnableAutoConfiguration 配置项,构成了 Spring Boot 自动配置的基石。

掌握 Spring Boot 自动装配的原理并能够自定义 Starter,是深入理解 Spring Boot 生态和构建可复用微服务架构组件的重要一步。它不仅能帮助开发者更好地使用现有框架,也为封装团队内部技术资产、统一技术栈提供了强大的工具。

参考资料

[1] SpringBoot自动装配原理+手写一个starter组件, 微信公众号:mp.weixin.qq.com/s/F_9Ux9LjuJ_h7oCr7fL9Zw

版权声明:本文由 云栈社区 整理发布,版权归原作者所有。




上一篇:Fluke 15B+ 数字万用表6年使用体验与内部电路深度解析
下一篇:融合车辆预测与动态占据栅格,为自动驾驶提供场景理解新框架
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-2-23 10:27 , Processed in 0.593546 second(s), 40 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表