详解SpringBoot如何自定义自己的Starter组件
一、为什么要自定义starter
在我们的日常开发工作中,经常会有一些独立于业务之外的配置模块,我们经常将其放到一个特定的 包下,然后如果另一个工程需要复用这块功能的时候,需要将代码硬拷贝到另一个工程,重新集成一 遍,麻烦至极。如果我们将这些可独立于业务代码之外的功能配置模块封装成一个个starter,复用的时 候只需要将其在pom中引用依赖即可,SpringBoot为我们完成自动装配,简直不要太爽。
二、starter的实现
虽然不同的starter
实现起来各有差异,但是他们基本上都会使用到两个相同的内容:ConfigurationProperties
和AutoConfiguration
。因为Spring Boot
坚信“约定大于配置”这一理念,所以我们使用ConfigurationProperties来保存我们的配置,并且这些配置都可以有一个默认值,即在我们没有主动覆写原始配置的情况下,默认值就会生效,这在很多情况下是非常有用的。除此之外,starter
的ConfigurationProperties
还使得所有的配置属性被聚集到一个文件中(一般在resources目录下的application.properties),这样我们就告别了Spring项目中XML地狱。
三、命名规范
如果你快有孩子了,出生前你比较急的一定是起个名字。孩子的姓名标识着你和你爱人的血统,一定不会起隔壁老王的姓氏,肯定会招来异样的眼光。在maven
中,groupId
代表着姓氏,artifactId
代表着名字。Spring Boot
也是有一个命名的建议的。所以名字是不能够随随便便取得,可以按照官方的建议来取。
What’s in a name All official starters follow a similar naming pattern; spring-boot-starter-, whereis a particular type of application. This naming structure is intended to help when you need to find a starter. The Maven integration in many IDEs lets you search dependencies by name. For example, with the appropriate Eclipse or STS plugin installed, you can press ctrl-space in the POM editor and type “spring-boot-starter” for a complete list. As explained in the “Creating Your Own Starter” section, third party starters should not start with spring-boot, as it is reserved for official Spring Boot artifacts. Rather, a third-party starter typically starts with the name of the project. For example, a third-party starter project called thirdpartyproject would typically be named thirdpartyproject-spring-boot-starter.
大概意思:官方的 starter
的命名格式为 spring-boot-starter-{xxxx}
比如spring-boot-starter-activemq,
第三方我们自己的命名格式为 {xxxx}-spring-boot-starter
。比如mybatis-spring-boot-starter
。如果我们忽略这种约定,是不是会显得我们写的东西不够“专业“。
四、代码工程
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <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"> <parent> <artifactId>springboot-demo</artifactId> <groupId>com.et</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>xxx-spring-boot-starter</artifactId> <properties> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> </properties> <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>
属性文件
com.person.age=23 com.person.name=Lynch com.person.sex=F
自动配置类
package com.et.config; import com.et.service.PersonService; import com.et.starter.PersonProperties; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; 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(PersonProperties.class) @ConditionalOnClass(PersonService.class) @ConditionalOnProperty(prefix = "com.person", value = "enabled", matchIfMissing = true) public class PersonServiceAutoConfiguration { @Autowired private PersonProperties properties; // if spring container do not config bean,auto config PersonService @Bean @ConditionalOnMissingBean(PersonService.class) public PersonService personService(){ PersonService personService = new PersonService(properties); return personService; } }
service类
package com.et.service; import com.et.starter.PersonProperties; public class PersonService { private PersonProperties properties; public PersonService() { } public PersonService(PersonProperties properties) { this.properties = properties; } public void sayHello() { String message = String.format("hi,my name: %s, today,I'am %s , gender: %s", properties.getName(), properties.getAge(), properties.getSex()); System.out.println(message); } }
PersonProperties
package com.et.starter; import java.io.Serializable; import org.springframework.boot.context.properties.ConfigurationProperties; @SuppressWarnings("serial") @ConfigurationProperties(prefix = "com.person") public class PersonProperties implements Serializable { private String name; private int age; private String sex = "M"; public PersonProperties() { } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } }
spring.factories文件
/META-INF/spring.factories文件放在/src/main/resources目录下 注意:META-INF是自己手动创建的目录,spring.factories也是自己手动创建的文件,在该文件中配置自己的自动配置类。
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.et.config.PersonServiceAutoConfiguration
项目打包
mvn clean install
代码仓库
github.com/Harries/springboot-demo
五、测试
在另外一个项目中添加starter的依赖
<dependency> <groupId>com.et</groupId> <artifactId>xxx-spring-boot-starter</artifactId> <version>1.0-SNAPSHOT</version> </dependency>
单元测试类
package com.et.starter; import com.et.service.PersonService; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest public class PersonServiceTest { @Autowired private PersonService personService; @Test public void testHelloWorld() { personService.sayHello(); } }
运行测试类
2024-03-11 10:35:18.374 INFO 10960 --- [ main] com.et.starter.PersonServiceTest : Starting PersonServiceTest on BJDPLHHUAPC with PID 10960 (started by Dell in D:\IdeaProjects\ETFramework\xxx-spring-boot-starter-test)
2024-03-11 10:35:18.376 INFO 10960 --- [ main] com.et.starter.PersonServiceTest : No active profile set, falling back to default profiles: default
2024-03-11 10:35:19.387 INFO 10960 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
2024-03-11 10:35:19.657 INFO 10960 --- [ main] com.et.starter.PersonServiceTest : Started PersonServiceTest in 1.507 seconds (JVM running for 2.188)
hi,my name: Lynch, today,I'am 23 , gender: F
2024-03-11 10:35:19.827 INFO 10960 --- [extShutdownHook] o.s.s.concurrent.ThreadPoolTaskExecutor : Shutting down ExecutorService 'applicationTaskExecutor'
以上就是详解SpringBoot如何自定义自己的Starter组件的详细内容,更多关于SpringBoot自定义Starter组件的资料请关注脚本之家其它相关文章!
相关文章
Spring Cloud Nacos 和 Eureka区别解析
Spring Cloud Nacos 和 Spring Cloud Eureka 都是 Spring Cloud 微服务框架中的服务注册和发现组件,用于帮助开发者轻松地构建和管理微服务应用,这篇文章主要介绍了Spring Cloud Nacos 和 Eureka区别,需要的朋友可以参考下2023-08-08解决Springboot项目报错:java:错误:不支持发行版本 17
这篇文章主要给大家介绍了关于解决Springboot项目报错:java:错误:不支持发行版本17的相关资料,这个错误意味着你的Spring Boot项目正在使用Java 17这个版本,但是你的项目中未配置正确的Java版本,需要的朋友可以参考下2023-08-08JAVA发送http get/post请求,调用http接口、方法详解
这篇文章主要介绍了Java发送http get/post请求调用接口/方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧2019-04-04
最新评论