Springboot的starter有什么用以及如何自定义一个starter
SpringBoot的starter是什么
我们都知道SpringBoot的目的就是为了让开发者尽可能的减少项目配置专注于程序代码的编写,而'starter'就是SpringBoot简便开发、自动装配的具体实现。
以‘mybatis-spring-boot-starter’为例:
<dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>3.0.2</version> </dependency>
在项目的“External Libraries”中找到‘mybatis-spring-boot-starter’并分析一下结构:
只有三个文件:pom.properties、pom.xml、MANIFEST.MF,其中pom.properties和MANIFEST.MF内容都是mybatis-starter的一些配置信息,而pom.xml中是mybatis-starter所管理的一些依赖,可以看到表面上只引入一个starter的依赖,但就是这一个starter几乎包含了所需要的其他依赖,这就体现了starter“依赖管理”的特性。
pom.properties:
artifactId=mybatis-spring-boot-starter groupId=org.mybatis.spring.boot version=3.0.2
MANIFEST.MF:
Manifest-Version: 1.0 Created-By: Apache Maven Bundle Plugin 5.1.8 Build-Jdk-Spec: 17 Specification-Title: mybatis-spring-boot-starter Specification-Version: 3.0 Specification-Vendor: MyBatis.org Implementation-Title: mybatis-spring-boot-starter Implementation-Version: 3.0.2 Implementation-Vendor: MyBatis.org Automatic-Module-Name: org.mybatis.spring.boot.starter Copyright: 2022 X-Compile-Release-JDK: 17 X-Compile-Source-JDK: 17 X-Compile-Target-JDK: 17 Bundle-Description: Spring Boot Support for MyBatis Bundle-DocURL: https://www.mybatis.org/spring-boot-starter/mybatis-sprin g-boot-starter/ Bundle-License: https://www.apache.org/licenses/LICENSE-2.0.txt Bundle-ManifestVersion: 2 Bundle-Name: mybatis-spring-boot-starter Bundle-SymbolicName: org.mybatis.spring.boot.mybatis-spring-boot-starter Bundle-Vendor: MyBatis.org Bundle-Version: 3.0.2 Git-Revision: 033cec2b1adb771d1815caa0c99b5f45689b27c8 Tool: Bnd-6.4.0.202211291949
pom.xml:
<?xml version="1.0" encoding="UTF-8"?> <!-- Copyright 2015-2023 the original author or authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at https://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --> <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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot</artifactId> <version>3.0.2</version> </parent> <artifactId>mybatis-spring-boot-starter</artifactId> <name>mybatis-spring-boot-starter</name> <properties> <module.name>org.mybatis.spring.boot.starter</module.name> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-autoconfigure</artifactId> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> </dependency> </dependencies> </project>
接着分析pom.xml中“mybatis-spring-boot-autoconfigure”:
其中“MybatisAutoConfiguration”就是实现对Mybatis自动装配的类,其中可以看到相关的SqlSessionFactory、DataSource、DataSourceAutoConfiguration等关键字。也就是starter具有实现“自动装配”的功能。
如果继续往下看“DataSourceAutoConfiguration”类,会发现其中读取配置文件的规则符合springboot配置文件的规则,此处也体现了starter“约定优于配置”的特点:只需要按照springboot的约定规则就可以省去很多额外的配置。
总结,SpringBoot中的Starter的作用主要有以下三点:
1、依赖管理:starter可以一次性引入多个相关的依赖项,这些依赖项都是为了支持某个特定的功能或功能集合而设计的。通过引入starter,开发人员可以省去手动添加每个依赖项的步骤,简化了依赖管理的过程。
2、自动配置:starter包含了一些自动配置的类和配置文件,可以根据项目的需要自动配置Spring Boot应用程序的各种组件,例如数据库、消息队列、Web服务等。这样,开发人员可以避免手动配置大量的组件,减少了开发和维护的工作量。
3、约定优于配置:starter遵循了Spring Boot的约定优于配置的原则,提供了一种标准的配置方式,使得开发人员可以快速构建和部署应用程序。开发人员只需要按照starter的要求进行配置,即可获得默认的配置和功能。当项目需要定制化配置时,也可以通过覆盖默认配置来实现。
如何自定义一个springboot的starter(以获取UUID的自定义starter为例)
1、创建starter项目,命名规范为:
Spring官方Starter通常命名为spring-boot-starter-{name}如:spring-boot-starter-web
Spring官方建议非官方Starter命名应遵循{name}-spring-boot-starter的格式:如mybatis-spring-boot-starter。
2、引入依赖。需要引入两个核心依赖:
spring-boot-autoconfigure
spring-boot-configuration-processor
<dependencies>
<!-- springboot自动配置 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<version>2.5.3</version>
</dependency>
<!-- 用于关联配置文件和实体Bean -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<version>2.0.1.RELEASE</version>
<optional>true</optional>
</dependency>
</dependencies>
3、编写一个自动配置类。这是Spring Boot自动装配的核心,可以使用`@Configuration`注解进行标注。在类中,使用`@Bean`注解来声明需要自动装配的Bean。
@Configuration @ConditionalOnClass(value = {StringUtil.class}) @EnableConfigurationProperties(value = StrProperties.class) public class StrAutoConfiguration { @Bean @ConditionalOnMissingBean() public StringUtil getStringUtil() { return new StringUtil(); } }
这是跟配置文件相绑定的类,里边的属性就是我们可以在配置文件中配置的内容,然后通过@configurationproperties将其与配置文件绑定:
@ConfigurationProperties(prefix = "str.config") public class StrProperties { }
4、根据需求编写实际业务代码。
public class StringUtil { public String getUUID() { UUID uuid = UUID.randomUUID(); String uuidStr = uuid.toString().replace("-", ""); return uuidStr; } }
5、在resource的META-INF下编写spring.factories文件,将自动配置类编写到文件中。
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.demo.StrAutoConfiguration
6、在其他项目中引入此starter
<dependencies> <!--web访问--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>2.5.4</version> </dependency> <!--自定义starter--> <dependency> <groupId>com.code</groupId> <artifactId>str-spring-boot-starter</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies>
7、验证(编写一个controller,调用自定义starter中的功能)
@RestController public class TestController { @Autowired public StringUtil stringUtil; @RequestMapping("/test") public String getUUID() { return stringUtil.getUUID(); } }