你是否也有过这样的困扰?在开发 Spring Boot 项目时,每次引入新功能都要重复配置大量的依赖和参数,不仅繁琐,还容易出错。特别是在互联网大厂的复杂项目中,多个团队协作开发,这种重复的配置工作更是让开发效率大打折扣。其实,Spring Boot3 提供了一个强大的功能 —— 自定义 Starter,它能帮你轻松解决这些问题,大幅提升开发效率!
背景介绍
在互联网大厂的项目开发中,时间就是金钱,效率就是竞争力。随着项目规模的不断扩大,代码的复用性和可维护性变得尤为重要。Spring Boot 的 Starter 机制原本就为开发者提供了 “开箱即用” 的便利,通过引入对应的 Starter 依赖,就能快速集成某项功能。但在实际开发中,我们经常会遇到一些特定的业务需求或常用的功能模块,这些功能可能在多个项目中都会用到,如果每次都要重新配置,无疑是在浪费时间。而自定义 Starter 就是为了解决这个痛点而生,它可以将我们常用的功能进行封装,方便在不同项目中复用,实现代码的标准化和规范化。
比如,在一个电商项目中,可能多个服务都需要对商品数据进行特定格式的缓存处理,每次在新服务中搭建这个功能都要重新配置缓存相关的依赖、连接参数以及自定义的缓存处理逻辑等,非常繁琐。若将这些功能封装成一个自定义 Starter,后续新服务接入时,只需简单引入依赖,就能快速拥有该功能,大大提高开发效率。
创建项目并导入依赖
首先,我们需要创建一个新的 Spring Boot 项目。在项目的pom.xml文件中,导入spring-boot-autoconfigure依赖,它是 Spring Boot 自动配置的核心依赖,有了它才能实现我们自定义 Starter 的自动配置功能。如果希望在编写配置文件时有代码提示,还可以导入
spring-boot-configuration-processor依赖。同时,由于我们自定义的 Starter 不需要打成可自动启动的jar文件,所以要删除pom文件中build标签下的spring boot maven打包插件。
<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>
</dependencies>
这里的spring-boot-autoconfigure依赖至关重要,它为自动配置提供了基础框架。当我们后续编写自动配置类时,该依赖会帮助 Spring Boot 识别并加载这些配置。而
spring-boot-configuration-processor依赖主要用于生成配置元数据文件,在application.yml等配置文件中编写配置时,编辑器能根据这个元数据文件提供智能提示,方便我们准确配置各项参数。
定义属性类
属性类的作用是读取配置文件中的属性。我们可以通过@ConfigurationProperties注解来绑定配置文件中的属性值。例如,我们创建一个MyStarterProperties类:
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties(prefix = "my.starter")
public class MyStarterProperties {
private String name;
private int age;
// 省略getter和setter方法
}
在这个类中,我们定义了name和age两个属性,并通过@ConfigurationProperties(prefix = "my.starter")指定了配置文件中的属性前缀。这样,在application.yml文件中配置my.starter.name和my.starter.age,就能自动注入到这个类中。同时,我们还可以为属性设置默认值,当配置文件中没有明确指定值时,就会使用默认值;若配置文件中有值,则会覆盖默认值。
实际应用中,假设我们的自定义 Starter 是用于一个用户管理模块,可能会有user.name、user.defaultRole等属性。通过设置默认值,如user.defaultRole默认设为 “普通用户”,在大多数项目中如果没有特殊需求,就无需在配置文件中额外配置该属性,减少了配置工作量。但如果某个项目需要将新用户默认设为 “VIP 用户”,则可在application.yml中简单配置user.defaultRole: VIP用户,轻松覆盖默认值。
定义相关服务类和配置类
创建服务类,用于实现具体的业务逻辑。比如MyStarterService类:
import org.springframework.stereotype.Service;
@Service
public class MyStarterService {
private final MyStarterProperties properties;
public MyStarterService(MyStarterProperties properties) {
this.properties = properties;
}
public void doSomething() {
System.out.println("My Starter service is running, name: " + properties.getName() + ", age: " + properties.getAge());
}
}
在这个服务类中,我们通过构造函数注入了MyStarterProperties类,然后在doSomething方法中使用这些属性来执行具体的业务逻辑。
接着,创建配置类
MyStarterAutoConfiguration,将需要用到的类注册到 Spring 的 IOC 容器中:
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@ConditionalOnClass(MyStarterService.class)
@EnableConfigurationProperties(MyStarterProperties.class)
public class MyStarterAutoConfiguration {
@Bean
@ConditionalOnProperty(name = "my.starter.enabled", havingValue = "true")
public MyStarterService myStarterService(MyStarterProperties properties) {
return new MyStarterService(properties);
}
}
在这个配置类中,我们使用了@ConditionalOnClass注解,只有当类路径下存在MyStarterService.class时,才会生效;使用@
EnableConfigurationProperties注解启用属性类的配置;使用@ConditionalOnProperty注解,只有当配置文件中my.starter.enabled属性为true时,才会创建MyStarterService的bean。
这里的@ConditionalOnClass注解非常实用,它能确保在项目引入了相关类的依赖时,自动配置才会生效。比如,若我们的自定义 Starter 依赖于某个特定的数据库连接驱动类,通过这个注解可以避免在没有引入该驱动依赖时,因找不到类而导致的错误配置。而@ConditionalOnProperty注解则赋予了使用者在配置文件中灵活控制功能开启或关闭的能力。例如,在一些测试环境中,可能暂时不需要某些功能,通过在application.yml中设置my.starter.enabled: false,就可以关闭该自定义 Starter 的功能,方便进行环境切换和调试。
配置自动装配
在资源目录下创建META -
INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports文件,在该文件中指定配置类的全限定名,例如:
com.example.mystarter.MyStarterAutoConfiguration
另外,将spring - configuration - metadata.json文件复制一份到META - INF/spring目录下,这样在编写application.yml配置文件时,就会有自动提示,方便我们配置属性。
从 Spring Boot 3.0 开始,采用META -
INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports文件来替代之前的spring.factories文件进行自动配置类的加载。这种改变主要是为了更好地支持模块化和依赖管理。当 Spring Boot 启动时,它会扫描所有依赖库中的这个文件,读取其中指定的自动配置类,并根据各种条件注解(如前面提到的@ConditionalOnClass、@ConditionalOnProperty等)来决定是否加载和应用这些配置。而spring - configuration - metadata.json文件能让开发者在编写配置文件时,通过编辑器的智能提示,快速准确地了解和配置自定义 Starter 所支持的各项属性,极大地提高了配置的便捷性和准确性。
上传到 Maven 仓库
完成上述步骤后,在项目的根目录下,打开命令行工具,执行mvn clean install -DskipTests命令,或者在 IDEA 中使用 Maven 的生命周期工具,将自定义的 Starter 上传到本地的 Maven 仓库中。之后,在其他项目中,只需要引入我们自定义 Starter 的依赖,就可以使用其中的功能了。
<dependency>
<groupId>com.example</groupId>
<artifactId>my - starter</artifactId>
<version>1.0.0</version>
</dependency>
将自定义 Starter 上传到 Maven 仓库后,它就可以像其他公共依赖一样,方便地被多个项目引用。在团队开发中,不同的项目组可以基于这个共享的自定义 Starter 进行开发,保证了项目间功能实现的一致性和规范性。而且,当自定义 Starter 的功能有更新时,只需要更新 Maven 仓库中的版本,所有引用该 Starter 的项目都能受益,极大地提高了代码的复用性和维护效率。
总结
通过自定义 Starter,我们可以将常用的功能进行封装,提高代码的复用性和开发效率,这在互联网大厂的大型项目中尤为重要。希望各位后端开发的小伙伴,都能掌握这个技能,应用到实际项目开发中。如果你在实现自定义 Starter 的过程中有任何问题,或者有更好的实践经验,欢迎在评论区留言分享,让我们一起学习,共同进步!