当前位置: 代码网 > it编程>编程语言>Java > Spring Boot Starter 自动装配原理全解析

Spring Boot Starter 自动装配原理全解析

2025年04月24日 Java 我要评论
spring boot starter 的核心设计理念是 约定优于配置,其核心实现基于 自动配置(auto-configuration) 和 条件化注册(conditional registratio

spring boot starter 的核心设计理念是 约定优于配置,其核心实现基于 自动配置(auto-configuration)条件化注册(conditional registration)。以下是其生效原理:

约定大于配置

通过预定义合理的默认行为和规范,减少开发者需要手动配置的步骤。比较显著的变化就是减少xml配置。还有一些实际体现如下所示:

  • 项目结构约定
    • 默认目录结构:如 src/main/java 存放代码,src/main/resources 存放配置文件。
    • 配置文件命名application.propertiesapplication.yml 自动被加载,无需显式指定路径。
  • 自动配置(auto-configuration)
    • 条件化 bean 注册:根据类路径依赖(如存在 datasource 类)自动配置数据库连接池
    • 默认参数值:如嵌入式 tomcat 默认端口为 8080,无需手动指定。
  • starter 依赖
    • 依赖聚合:引入 spring-boot-starter-web 即自动包含 web 开发所需的所有依赖(如 tomcat、jackson、spring mvc)。
    • 开箱即用:无需手动管理版本兼容性。
  • restful 路由映射
    • 注解驱动:通过 @getmapping("/path") 即可定义接口,无需在 xml 中配置路由规则。

自动配置机制

触发阶段:@enableautoconfiguration

  • 应用启动时,@springbootapplication 组合了 @enableautoconfiguration,触发自动配置流程。
  • autoconfigurationimportselector 被调用,负责加载所有候选的自动配置类。
public string[] selectimports(annotationmetadata metadata) {
  // 1. 加载所有候选自动配置类
  list<string> configurations = getcandidateconfigurations();
  // 2. 去重、过滤、排序
  configurations = removeduplicates(configurations);
  configurations = filter(configurations, autoconfigurationmetadata);
  return configurations.toarray(new string[0]);
}

加载与筛选:spring.factories

  • 加载所有候选配置类

从所有 meta-inf/spring.factories 文件中读取 enableautoconfiguration 对应的配置类。在 spring boot 3.x 中,自动配置类的加载方式从 spring.factories 过渡到 autoconfiguration.imports,并引入了 importcandidates 类来处理这一变化。

  • 去重与过滤

移除重复的配置类,并通过条件注解(如 @conditionalonclass ,@conditionalonmissingbean ) 有选择的保留当前环境的配置类。

  • @conditionalonclass:类路径存在指定类时生效
  • @conditionalonmissingbean:容器中不存在指定 bean 时生效
  • @conditionalonproperty:配置属性匹配时生效

排序

根据 @autoconfigureorder@autoconfigureafter 调整配置类的加载顺序。

bean 注册

  • 筛选后的自动配置类被解析为标准的 @configuration 类。
  • 每个配置类中的 @bean 方法根据条件注解动态注册 bean 到 spring 容器。

编写自定义spring boot starter

项目结构规划

建议分为两个模块:

  • 自动配置模块:包含核心逻辑和自动配置类(如 hello-spring-boot-autoconfigure)。
  • starter模块:空项目,仅作为依赖聚合(如 hello-spring-boot-starter)。
hello-spring-boot-starter-parent(父pom)
├── hello-spring-boot-autoconfigure(自动配置模块)
└── hello-spring-boot-starter(starter模块)
hello-spring-boot-starter/
├── hello-spring-boot-autoconfigure/
│   ├── src/
│   │   ├── main/
│   │   │   ├── java/com/example/autoconfigure/
│   │   │   │   ├── helloautoconfiguration.java
│   │   │   │   ├── helloproperties.java
│   │   │   │   └── helloservice.java
│   │   │   └── resources/
│   │   │       └── meta-inf/
│   │   │           └── spring.factories
│   │   └── test/
│   └── pom.xml
├── hello-spring-boot-starter/
│   └── pom.xml
└── pom.xml

创建自动配置模块(hello-spring-boot-autoconfigure)

添加maven依赖

<!-- pom.xml -->
<dependencies>
    <!-- spring boot 自动配置基础依赖 -->
    <dependency>
        <groupid>org.springframework.boot</groupid>
        <artifactid>spring-boot-autoconfigure</artifactid>
        <version>3.1.5</version>
    </dependency>
    <!-- 可选:配置属性处理 -->
    <dependency>
        <groupid>org.springframework.boot</groupid>
        <artifactid>spring-boot-configuration-processor</artifactid>
        <version>3.1.5</version>
        <optional>true</optional>
    </dependency>
</dependencies>

定义核心服务类

public class helloservice {
    private string message = "hello, world!";  // 默认消息
    public string sayhello() {
        return message;
    }
    // getter和setter用于通过配置修改message
    public string getmessage() { return message; }
    public void setmessage(string message) { this.message = message; }
}

定义配置属性类(可选)

@configurationproperties(prefix = "hello")
public class helloproperties {
    private string message = "hello, world!";
    // getter和setter
    public string getmessage() { return message; }
    public void setmessage(string message) { this.message = message; }
}

编写自动配置类

@configuration
@enableconfigurationproperties(helloproperties.class)  // 启用配置属性
@conditionalonclass(helloservice.class)  // 当helloservice在类路径时生效
public class helloautoconfiguration {
    @bean
    @conditionalonmissingbean  // 当用户未自定义helloservice时生效
    public helloservice helloservice(helloproperties properties) {
        helloservice service = new helloservice();
        service.setmessage(properties.getmessage());
        return service;
    }
}

注册自动配置

resources/meta-inf/ 下创建 spring.factories 文件:

org.springframework.boot.autoconfigure.enableautoconfiguration=\
com.example.autoconfigure.helloautoconfiguration

创建starter模块(hello-spring-boot-starter)

添加maven依赖

<!-- pom.xml -->
<dependencies>
    <!-- 引入自动配置模块 -->
    <dependency>
        <groupid>com.example</groupid>
        <artifactid>hello-spring-boot-autoconfigure</artifactid>
        <version>1.0.0</version>
    </dependency>
</dependencies>

使用自定义starter

在应用中引入starter依赖

<!-- 用户项目的pom.xml -->
<dependency>
    <groupid>com.example</groupid>
    <artifactid>hello-spring-boot-starter</artifactid>
    <version>1.0.0</version>
</dependency>

在代码中注入bean

@restcontroller
public class hellocontroller {
    @autowired
    private helloservice helloservice;
    @getmapping("/hello")
    public string hello() {
        return helloservice.sayhello();
    }
}

自定义配置(可选)

application.properties 中修改消息:

hello.message=你好, spring boot!

到此这篇关于spring boot starter 自动装配原理的文章就介绍到这了,更多相关spring boot starter 自动装配内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com