自定义starter概念
将一些可独立于业务代码之外的功能和配置模块封装成一个个starter,SpringBoot会为我们完成自动装配,这样复用的时候只需要将其在pom中引用依赖即可。
自定义starter实现及原理
原理
命名规则
官方提供的starter:spring-boot-starter-xxx 的形式命名
举例:spring-boot-starter-aop
第三方自定义starter:xxx-spring-boot-starter 的形式命名
举例:mybatis-spring-boot-starter
创建步骤
创建工程
使用 IntelliJ IDEA 创建一个空项目(Empty Project)
通过Spring Initializr 创建两个Spring Boot模块,一个 hello-spring-boot-starter 和一个 hello-example。
添加 POM 依赖
定义 propertie 类
如果我们需要从 application.yaml 或 application.properties 中拿到一些使用者配置的数据,那么我们就需要定义一个properties类。这个properties类主要作用是将 application.yaml 或 application.properties 中的配置信息映射成实体类。
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
@Data
@ConfigurationProperties(prefix ="hello.test")
public class HelloProperties {
private boolean enable;
private String name;
private String url;
}
Service 类
import com.example.hellospringbootstarter.config.HelloProperties;
import org.springframework.beans.factory.annotation.Autowired;
public class HelloService {
@Autowired
private HelloProperties helloProperties;
public String sayHello() {
return "hello "+ helloProperties.getName() + " welcome to my homepage----------:" + helloProperties.getUrl();
}
}
定义配置类
@Configuration:表示该类是一个配置类;
@EnableConfigurationProperties(xxxProperties.class):该注解的作用是为 xxxProperties 开启属性配置功能,并将这个类以组件的形式注入到容器中;
@ConditionalOnProperty(prefix = "xxx", name= "x", matchIfMissing = true):当指定的配置项等于你想要的时候,配置类生效;
@ConditionalOnMissingBean(xxx.class):该注解表示当容器中没有 xxx 类时,该方法才生效;
@Bean:该注解用于将方法的返回值以 Bean 对象的形式添加到容器中。
import com.example.hellospringbootstarter.service.HelloService;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
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
@EnableConfigurationProperties(HelloProperties.class)
@ConditionalOnProperty(prefix = "hello.test", name = "enable", matchIfMissing = true)
public class HelloAutoConfiguration {
@Bean
@ConditionalOnMissingBean(HelloService.class)
public HelloService helloService() {
return new HelloService();
}
}
spring.factories 文件
Spring Factories 机制是 Spring Boot 中的一种服务发现机制,这种扩展机制与 Java SPI 机制十分相似。Spring Boot 会自动扫描所有 Jar 包类路径下 META-INF/spring.factories 文件,并读取其中的内容,进行实例化,这种机制也是 Spring Boot Starter 的基础。因此我们自定义 starter 时,需要在项目类路径下创建一个 spring.factories 文件。
在 hello-spring-boot-starter 的路径下(resources )中创建一个 META-INF 文件夹,并在 META-INF 文件夹中创建一个 spring.factories 文件。
将 Spring Boot 的 EnableAutoConfiguration 接口与自定义 starter 的自动配置类 HelloAutoConfiguration 组成一组键值对添加到 spring.factories 文件中,以方便 Spring Boot 在启动时,获取到自定义 starter 的自动配置:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.hellospringbootstarter.config.HelloAutoConfiguration
构建 starter
hello-spring-boot-starter 下执行 mvn clean install
验证
在hello-example下pom.xml中添加我们自定义的 hello-spring-boot-starter:
<!--引入自定义starter-->
<dependency>
<groupId>com.example</groupId>
<artifactId>hello-spring-boot-starter</artifactId>
<version>20230213</version>
</dependency>
在 application.yaml 或 application.properties 中配置如下:
hello.test.enable=true
hello.test.name=tzp
hello.test.url=ll
测试类
import com.example.hellospringbootstarter.service.HelloService;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@Slf4j
@SpringBootTest
class HelloExampleApplicationTests {
@Autowired
HelloService helloService;
@Test
void contextLoads() {
log.info(helloService.sayHello());
}
}