晚上八点,办公室里只剩零星几盏灯倔强地亮着,时不时响起键盘的噼啪声音。
我伸了个懒腰,揉了揉发酸的眼睛,心想,工作告一段落,一天窝囊费到手,撤。这时,小悠抱着笔记本电脑,脚步匆匆地走了过来,发梢扫过她泛红的脸颊,像是染上了晚霞的颜色。
“嘿!飞哥,先别溜!” 她把电脑往我桌上一放,“我最近在学习spring boot starter,本来想着引入现成的依赖就能轻松搞定,结果搞了一下午还是搞不定,我都快抑郁了!” 。
我凑近一看,屏幕上满是红色的报错信息,像极了她此刻烦躁的心情。 “多大点事儿。Spring Boot 自定义 starter 确实是个好东西,能把那些重复又繁琐的配置封装起来,以后想用相关功能,直接引入咱们自己的 starter 就行了“来,我给你说道说道。
我一边打开IDEA,一边解释:“首先,咱们要知道一个自定义 starter 的基本结构。它就像是一个精心包装的礼物盒,里面包含了各种必要的礼物。一般来说,它需要有一个自动配置类,这可是核心部分,就像礼物盒的钥匙,用来告诉 Spring Boot 该怎么初始化相关的组件和配置。” 说着,我敲下了一段代码:
import org.springframework.context.annotation.Configuration;
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;
@Configuration
@ConditionalOnClass(MyService.class)
@EnableConfigurationProperties(MyProperties.class)
public class MyAutoConfiguration {
private final MyProperties myProperties;
public MyAutoConfiguration(MyProperties myProperties) {
this.myProperties = myProperties;
}
@Bean
@ConditionalOnProperty(name = "my.enabled", havingValue = "true")
public MyService myService() {
return new MyService(myProperties.getMessage());
}
}
小悠盯着代码,眉头紧锁,睫毛在眼下投出一片小小的阴影:“这 ConditionalOnClass、ConditionalOnProperty 都是啥意思啊?”
我:“ConditionalOnClass 就是条件注解,它表示只有当类路径下存在指定的类时,这个配置才会生效。就好比只有当你拥有某把特定的钥匙,才能打开对应的宝箱。而 ConditionalOnProperty 呢,是根据配置文件中的属性值来决定是否生效,像刚刚代码里的‘my.enabled’,只有当这个属性值为‘true’时,myService 这个 bean 才会被创建。” 她似懂非懂地点头,长发蹭到了我的手臂,痒痒的。
小悠眨了眨眼:“原来是这样!那这个 MyProperties 类又是做什么的呀?” 我接着说道:“它是用来读取配置文件里咱们自定义的属性的。你看。” 我又新建了一个类:
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties(prefix = "my")
public class MyProperties {
private String message;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
“在配置文件里,只要写‘my.message=你好小悠’,这里的 message 就能读取到对应的值,方便我们灵活配置。哦对了,这里用到的MyService类,是一个自定义的业务类,用于实现具体的业务逻辑,比如这样定义:” 我又补充了一段代码:
public class MyService {
private final String message;
public MyService(String message) {
this.message = message;
}
public String doSomething() {
return "执行自定义操作,获取到的信息是:" + message;
}
}
“在实际项目中,你可以根据具体需求,在MyService里编写更复杂的业务代码,doSomething方法只是一个示例,你可以添加更多的方法,实现不同的功能。” 我解释道。小悠突然凑近,呼吸扫过我的侧脸:“要是我还是不会,你可要一直教我哦。” 我心跳漏了一拍,佯装镇定地点头。
小悠兴奋地说:“明白了!那接下来是不是就可以把这个自定义 starter 用起来啦?” 我点点头:“没错,但还有关键的一步,就是要告诉 Spring Boot 这是一个自动配置类。我们需要在 src/main/resources/META-INF/spring.factories 文件里添加配置。” 我快速创建了这个文件,并写入内容:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.starter.MyAutoConfiguration
“这样,Spring Boot 启动的时候,就会自动加载我们的自定义配置类了。” 我说完,转头看向小悠。她已经迫不及待地开始创建自己的项目,不过,很快她又皱起眉头,委屈巴巴地说:“哎呀,引入之后怎么报错了,说找不到相关的依赖!” 我说:"修改一下 pom.xml 文件就可以了“
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.youyou</groupId>
<artifactId>my-spring-boot-starter</artifactId>
<version>1.0.0</version>
<dependencies>
<!--其他依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
经过一番折腾,小悠终于成功引入了自定义 starter,项目顺利启动。 我笑着说:“这只是入门,自定义 starter 还有很多高级玩法,比如整合更多的第三方库,优化配置的灵活性。以后遇到问题,随时叫我,嗯?但是得请我喝奶茶”。
第二天,小悠拿着杯奶茶踩着轻快的步子找到了我。“昨天太晚了,还没说完呢,我现在有个新工程,想用咱们之前开发的自定义 starter,该怎么操作呀?” 她边帮我插好吸管,一边看着我。
我打开IDEA:“首先,你得确保咱们的自定义 starter 已经打包成 jar 包了。还记得之前在 pom.xml 里配置的打包插件吧?在 IDEA 的 Maven 窗口中,找到 Lifecycle,点击 package,就能把 starter 打包成 jar。打包好之后,如果你只是在本地项目使用,可以把 jar 包安装到本地 Maven 仓库。在命令行进入到 starter 项目的根目录,执行mvn install命令,这样本地仓库就有这个 starter 了。” 我操作完后,继续说:“接下来,在新工程的 pom.xml 文件里添加依赖。就像这样:” 我在新工程的 pom.xml 中添加了如下代码:
<dependency>
<groupId>com.youyou</groupId>
<artifactId>my-spring-boot-starter</artifactId>
<version>1.0.0</version>
</dependency>
“添加完依赖,刷新一下 Maven,让项目下载相关的 jar 包。” 我点击了刷新按钮,“最后,别忘了在新工程的 application.properties 或者 application.yml 文件里,配置咱们 starter 需要的参数,比如刚刚定义的my.message。像这样在 application.yml 里写:
my:
enabled: true
message: "你好小悠"
保存配置,启动项目,你就能使用 starter 里封装的功能了。”
旁边工位阿强也来了:”飞哥,一大早喝奶茶呢,哦,你们俩在研究什么呢”
我猛吸一口奶茶:“去去去,瞎打听啥,写你的bug去。”
小悠:“谢谢飞哥”,一溜烟的跑回自己工位上。