国家电网Java面试被问:Spring Boot Starter 制作原理

Spring Boot Starter 制作原理

Spring Boot Starter 是 Spring Boot 的核心特性之一,它通过自动配置简化了依赖管理和配置。下面详细解释其制作原理:

一、核心概念

1. Starter 的本质

  • 依赖集合包 :Starter 本身是一个空的 JAR 文件,只包含 pom.xml,用于聚合相关依赖

  • 自动配置类 :通过 spring.factoriesMETA-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 文件提供自动配置类

  • 配置属性类 :定义可通过 application.propertiesapplication.yml 配置的属性

二、关键组件

1. 自动配置原理

java

复制

下载

复制代码
@Configuration  // 声明为配置类
@ConditionalOnClass  // 类路径下存在指定类时生效
@ConditionalOnProperty  // 配置文件中存在指定属性时生效
@EnableConfigurationProperties  // 启用配置属性绑定
@AutoConfigureAfter  // 指定自动配置顺序
public class MyAutoConfiguration {
    
    @Bean
    @ConditionalOnMissingBean  // 容器中不存在该 Bean 时创建
    public MyService myService(MyProperties properties) {
        return new MyService(properties);
    }
}

2. 条件注解

Spring Boot 提供了丰富的条件注解:

  • @ConditionalOnClass:类路径存在指定类

  • @ConditionalOnMissingBean:容器中不存在指定 Bean

  • @ConditionalOnProperty:配置属性匹配条件

  • @ConditionalOnWebApplication:Web 应用环境

  • @ConditionalOnExpression:SpEL 表达式条件

三、制作步骤

1. 项目结构

text

复制

下载

复制代码
my-spring-boot-starter/
├── src/main/java/
│   └── com/example/
│       ├── MyService.java          // 核心服务类
│       ├── MyProperties.java       // 配置属性类
│       ├── MyAutoConfiguration.java // 自动配置类
│       └── MyStarterApplication.java // 可选:演示应用
├── src/main/resources/
│   └── META-INF/
│       ├── spring.factories        // 传统方式(Spring Boot 2.6-)
│       └── spring/
│           └── org.springframework.boot.autoconfigure.AutoConfiguration.imports // 新方式(Spring Boot 2.7+)
└── pom.xml

2. pom.xml 配置

xml

复制

下载

运行

复制代码
<?xml version="1.0" encoding="UTF-8"?>
<project>
    <modelVersion>4.0.0</modelVersion>
    
    <groupId>com.example</groupId>
    <artifactId>my-spring-boot-starter</artifactId>
    <version>1.0.0</version>
    
    <properties>
        <spring-boot.version>3.1.0</spring-boot.version>
    </properties>
    
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    
    <dependencies>
        <!-- 必须依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        
        <!-- 你的 Starter 需要的依赖 -->
        <dependency>
            <groupId>com.example</groupId>
            <artifactId>my-library</artifactId>
            <version>1.0.0</version>
        </dependency>
    </dependencies>
</project>

篇幅限制下面就只能给大家展示小册部分内容了。整理了一份核心面试笔记包括了:Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafc

需要全套面试笔记及答案
【点击此处即可/免费获取】

3. 配置属性类

java

复制

下载

复制代码
@ConfigurationProperties(prefix = "my.service")
public class MyProperties {
    
    private String name = "default";
    private int timeout = 5000;
    private List<String> servers = new ArrayList<>();
    
    // getters and setters
}

4. 自动配置类

java

复制

下载

复制代码
@Configuration
@EnableConfigurationProperties(MyProperties.class)
@ConditionalOnClass(MyService.class)
@AutoConfigureAfter(DataSourceAutoConfiguration.class)
public class MyAutoConfiguration {
    
    @Bean
    @ConditionalOnMissingBean
    public MyService myService(MyProperties properties) {
        MyService service = new MyService();
        service.setName(properties.getName());
        service.setTimeout(properties.getTimeout());
        return service;
    }
    
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(prefix = "my.service", name = "enabled", havingValue = "true", matchIfMissing = true)
    public MyFeature myFeature() {
        return new MyFeature();
    }
}

5. 注册自动配置

Spring Boot 2.7+(推荐)

创建文件:src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

text

复制

下载

复制代码
com.example.MyAutoConfiguration
Spring Boot 2.6 及之前

创建文件:src/main/resources/META-INF/spring.factories

properties

复制

下载

复制代码
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
  com.example.MyAutoConfiguration

四、高级特性

1. 自定义条件注解

java

复制

下载

复制代码
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(OnMyCondition.class)
public @interface ConditionalOnMyFeature {
    String value();
}

public class OnMyCondition implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        // 自定义条件判断逻辑
        return true;
    }
}

2. 配置提示(IDE 支持)

创建 additional-spring-configuration-metadata.json

json

复制

下载

复制代码
{
  "properties": [
    {
      "name": "my.service.name",
      "type": "java.lang.String",
      "description": "服务名称",
      "defaultValue": "default"
    },
    {
      "name": "my.service.timeout",
      "type": "java.lang.Integer",
      "description": "超时时间(毫秒)",
      "defaultValue": 5000
    }
  ]
}

3. 多模块 Starter

xml

复制

下载

运行

复制代码
<!-- 父模块 -->
<artifactId>my-spring-boot-starter</artifactId>
<packaging>pom</packaging>
<modules>
    <module>my-spring-boot-autoconfigure</module>
    <module>my-spring-boot-starter-core</module>
</modules>

<!-- 自动配置模块 -->
<artifactId>my-spring-boot-autoconfigure</artifactId>

<!-- 依赖模块 -->
<artifactId>my-spring-boot-starter</artifactId>
<dependencies>
    <dependency>
        <groupId>com.example</groupId>
        <artifactId>my-spring-boot-autoconfigure</artifactId>
    </dependency>
</dependencies>

篇幅限制下面就只能给大家展示小册部分内容了。整理了一份核心面试笔记包括了:Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafc

需要全套面试笔记及答案
【点击此处即可/免费获取】

五、最佳实践

1. 命名规范

  • 官方 Starter:spring-boot-starter-{name}

  • 第三方 Starter:{name}-spring-boot-starter

2. 设计原则

  • 按需加载:使用条件注解确保只在合适的环境下生效

  • 默认配置:提供合理的默认值,减少用户配置

  • 外部化配置:所有配置都应支持外部化

  • 向后兼容:版本升级时保持 API 兼容性

3. 测试 Starter

java

复制

下载

复制代码
@SpringBootTest
@EnableConfigurationProperties
class MyAutoConfigurationTest {
    
    @Autowired(required = false)
    private MyService myService;
    
    @Test
    void testAutoConfiguration() {
        assertThat(myService).isNotNull();
    }
}

六、工作原理总结

  1. 启动时扫描 :Spring Boot 启动时扫描所有 META-INF/spring.factoriesAutoConfiguration.imports 文件

  2. 加载配置类:读取并加载所有自动配置类

  3. 条件评估:根据条件注解判断是否启用配置

  4. 创建 Bean :满足条件时,自动配置类中的 @Bean 方法被执行

  5. 属性绑定@ConfigurationProperties 将配置文件中的属性绑定到 Bean

通过这种机制,Starter 能够智能地根据项目环境和配置,自动装配所需的组件,大大简化了 Spring 应用的配置工作。

相关推荐
一 乐2 小时前
酒店预约|基于springboot + vue酒店预约系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·后端
LYFlied2 小时前
【每日算法】LeetCode 136. 只出现一次的数字
前端·算法·leetcode·面试·职场和发展
guslegend2 小时前
Tomact高级使用及原理剖析
java
Code blocks3 小时前
SpringBoot从0-1集成Minio对象存储
java·spring boot·后端
故渊ZY3 小时前
MyBatis事务原理与实战指南
java·mybatis
HTouying3 小时前
线程池【工具类】
java
深盾科技3 小时前
融合C++与Python:兼顾开发效率与运行性能
java·c++·python
我待_JAVA_如初恋3 小时前
idea创建MavenJavaWeb项目以后,包结构缺java
java·ide·intellij-idea
来深圳3 小时前
leetcode 739. 每日温度
java·算法·leetcode