前言

制定starter包目的为,约束和统一企业内的开发组件的版本,减少应用代码的配置内容。使得我们在开发业务代码时能够非常方便的、不需要过多关注框架的配置,而只需要关注业务即可。

原理

我们知道使用一个公用的starter的时候,只需要将相应的依赖添加的Maven的配置文件当中即可,免去了自己需要引用很多依赖类,并且SpringBoot会自动进行类的自动配置。那么 SpringBoot 是如何知道要实例化哪些类,并进行自动配置的呢? 下面简单说一下。

首先,SpringBoot 在启动时会去依赖的starter包中寻找 resources/META-INF/spring.factories 文件,然后根据文件中配置的Jar包去扫描项目所依赖的Jar包,这类似于 Java 的 SPI 机制。

第二步,根据 spring.factories配置加载AutoConfigure类。

最后,根据 @Conditional注解的条件,进行自动配置并将Bean注入Spring Context 上下文当中。

我们也可以使用@ImportAutoConfiguration({MyServiceAutoConfiguration.class}) 指定自动配置哪些类。

实现

创建一个SpringBoot 项目,并添加下面两个依赖到pom.xml文件当中

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-configuration-processor</artifactId>
   <optional>true</optional>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-autoconfigure</artifactId>
</dependency>

其中 spring-boot-configuration-processor 的作用是编译时生成 spring-configuration-metadata.json ,此文件主要给IDE使用。如当配置此jar相关配置属性在 application.yml ,你可以用ctlr+鼠标左键点击属性名,IDE会跳转到你配置此属性的类中。

我们日常使用的Spring官方的Starter一般采取spring-boot-starter-{name} 的命名方式,如 spring-boot-starter-web 

而非官方的Starter,官方建议 artifactId 命名应遵循{name}-spring-boot-starter 的格式。

因需制作的Starter包比较多,在这里我制作了starter-parent包,pom文件如下:

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>com.phenix</groupId>
	<artifactId>phenix-spring-boot-starter-parent</artifactId>
	<version>1.0.0-SNAPSHOT</version>
	<name>phenix-spring-boot-starter-parent</name>
	<description>定制加启动包</description>
	<packaging>pom</packaging>

	<properties>
		<java.version>1.8</java.version>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
		<spring.boot.version>2.1.9.RELEASE</spring.boot.version>
		<spring-cloud.version>Greenwich.SR3</spring-cloud.version>
		<spring-cloud-stream.version>Germantown.RELEASE</spring-cloud-stream.version>
		<spring-cloud-alibaba.version>0.9.0.RELEASE</spring-cloud-alibaba.version>

		<lombok.version>1.18.10</lombok.version>
		<commons-lang.version>3.9</commons-lang.version>
		<fastjson.version>1.2.62</fastjson.version>
		<starter.version>2.2.1.RELEASE</starter.version>
		<!-- aop -->
		<spring-boot-starter-aop.version>2.0.1.RELEASE</spring-boot-starter-aop.version>
		<javax.el.version>3.0.1-b08</javax.el.version>

		<hutool-all.version>5.0.3</hutool-all.version>
		<!--starter版本 -->
		<phenix-spring-boot-starter-parent.version>1.0.0-SNAPSHOT</phenix-spring-boot-starter-parent.version>
		<phenix-spring-boot-starter-admin.version>1.0.0-SNAPSHOT</phenix-spring-boot-starter-admin.version>
		<phenix-spring-boot-starter-feign.version>1.0.0-SNAPSHOT</phenix-spring-boot-starter-feign.version>
		<phenix-spring-boot-starter-logging.version>1.0.0-SNAPSHOT</phenix-spring-boot-starter-logging.version>
		<phenix-spring-boot-starter-mybatis-plus.version>1.0.0-SNAPSHOT</phenix-spring-boot-starter-mybatis-plus.version>
		<phenix-spring-boot-starter-mysql.version>1.0.0-SNAPSHOT</phenix-spring-boot-starter-mysql.version>
		<phenix-spring-boot-starter-nacos.version>1.0.0-SNAPSHOT</phenix-spring-boot-starter-nacos.version>
		<phenix-spring-boot-starter-rabbitmq.version>1.0.0-SNAPSHOT</phenix-spring-boot-starter-rabbitmq.version>
		<phenix-spring-boot-starter-redis.version>1.0.0-SNAPSHOT</phenix-spring-boot-starter-redis.version>
		<phenix-spring-boot-starter-swagger.version>1.0.0-SNAPSHOT</phenix-spring-boot-starter-swagger.version>
		<phenix-spring-boot-starter-web.version>1.0.0-SNAPSHOT</phenix-spring-boot-starter-web.version>
		<phenix-spring-boot-starter-security.version>1.0.0-SNAPSHOT</phenix-spring-boot-starter-security.version>
	</properties>

	<dependencies>
		<!-- spring-boot-starter -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter</artifactId>
		</dependency>
		<!-- commons-tool  -->
		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-lang3</artifactId>
			<version>${commons-lang.version}</version>
		</dependency>
		<!-- test  -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		<!-- 健康检查  -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-actuator</artifactId>
		</dependency>
		<!-- configuration-processor  -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-configuration-processor</artifactId>
			<optional>true</optional>
		</dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
		<!-- lombok -->
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<scope>provided</scope>
			<version>${lombok.version}</version>
		</dependency>

		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>fastjson</artifactId>
			<version>${fastjson.version}</version>
		</dependency>

		<dependency>
			<groupId>cn.hutool</groupId>
			<artifactId>hutool-all</artifactId>
			<version>${hutool-all.version}</version>
		</dependency>
	</dependencies>

	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-dependencies</artifactId>
				<version>${spring.boot.version}</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
			<dependency>
				<groupId>org.springframework.cloud</groupId>
				<artifactId>spring-cloud-dependencies</artifactId>
				<version>${spring-cloud.version}</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
			<!-- lombok -->
			<dependency>
				<groupId>org.projectlombok</groupId>
				<artifactId>lombok</artifactId>
				<scope>provided</scope>
				<version>${lombok.version}</version>
			</dependency>

			<dependency>
				<groupId>com.alibaba</groupId>
				<artifactId>fastjson</artifactId>
				<version>${fastjson.version}</version>
			</dependency>

			<dependency>
				<groupId>cn.hutool</groupId>
				<artifactId>hutool-all</artifactId>
				<version>${hutool-all.version}</version>
			</dependency>
			<dependency>
				<groupId>com.phenix</groupId>
				<artifactId>phenix-spring-boot-starter-web</artifactId>
				<version>${phenix-spring-boot-starter-web.version}</version>
			</dependency>
			<dependency>
				<groupId>com.phenix</groupId>
				<artifactId>phenix-spring-boot-starter-logging</artifactId>
				<version>${phenix-spring-boot-starter-logging.version}</version>
			</dependency>
			<dependency>
				<groupId>com.phenix</groupId>
				<artifactId>phenix-spring-boot-starter-swagger</artifactId>
				<version>${phenix-spring-boot-starter-swagger.version}</version>
			</dependency>
			<dependency>
				<groupId>com.phenix</groupId>
				<artifactId>phenix-spring-boot-starter-nacos</artifactId>
				<version>${phenix-spring-boot-starter-nacos.version}</version>
			</dependency>
			<dependency>
				<groupId>com.phenix</groupId>
				<artifactId>phenix-spring-boot-starter-mysql</artifactId>
				<version>${phenix-spring-boot-starter-mysql.version}</version>
			</dependency>
			<dependency>
				<groupId>com.phenix</groupId>
				<artifactId>phenix-spring-boot-starter-mybatis-plus</artifactId>
				<version>${phenix-spring-boot-starter-mybatis-plus.version}</version>
			</dependency>
			<dependency>
				<groupId>com.phenix</groupId>
				<artifactId>phenix-spring-boot-starter-admin</artifactId>
				<version>${phenix-spring-boot-starter-admin.version}</version>
			</dependency>
			<dependency>
				<groupId>com.phenix</groupId>
				<artifactId>phenix-spring-boot-starter-redis</artifactId>
				<version>${phenix-spring-boot-starter-redis.version}</version>
			</dependency>
			<dependency>
				<groupId>com.phenix</groupId>
				<artifactId>phenix-spring-boot-starter-rabbitmq</artifactId>
				<version>${phenix-spring-boot-starter-rabbitmq.version}</version>
			</dependency>
			<dependency>
				<groupId>com.phenix</groupId>
				<artifactId>phenix-spring-boot-starter-feign</artifactId>
				<version>${phenix-spring-boot-starter-feign.version}</version>
			</dependency>
			<dependency>
				<groupId>com.phenix</groupId>
				<artifactId>phenix-spring-boot-starter-security</artifactId>
				<version>${phenix-spring-boot-starter-security.version}</version>
			</dependency>
		</dependencies>
	</dependencyManagement>

	<build>
		<finalName>${project.artifactId}</finalName>
		<pluginManagement>
			<plugins>
				<!-- 发布插件 -->
				<plugin>
					<groupId>org.apache.maven.plugins</groupId>
					<artifactId>maven-release-plugin</artifactId>
					<configuration>
						<!--<preparationGoals>clean package</preparationGoals>-->
						<autoVersionSubmodules>true</autoVersionSubmodules>
						<!-- 不使用默认的profile -->
						<tagNameFormat>v@{project.version}</tagNameFormat>
						<useReleaseProfile>false</useReleaseProfile>
						<!--  在发布时不检查是否提交 git 的文件过滤配置 -->
						<allowReleasePluginSnapshot>true</allowReleasePluginSnapshot>
						<allowTimestampedSnapshots>true</allowTimestampedSnapshots>
						<checkModificationExcludes>
							<checkModificationExclude>.project</checkModificationExclude>
							<checkModificationExclude>.settings</checkModificationExclude>
							<checkModificationExclude>.classpath</checkModificationExclude>
							<checkModificationExclude>**\.project</checkModificationExclude>
							<checkModificationExclude>**\.settings</checkModificationExclude>
							<checkModificationExclude>**\.classpath</checkModificationExclude>
						</checkModificationExcludes>
						<!--<commitByProject>true</commitByProject>-->
					</configuration>
					<dependencies>
						<dependency>
							<groupId>org.apache.maven.scm</groupId>
							<artifactId>maven-scm-provider-gitexe</artifactId>
							<version>1.9.4</version>
						</dependency>
					</dependencies>
				</plugin>
				<!-- 生成sources源码包的插件 -->
				<plugin>
					<groupId>org.apache.maven.plugins</groupId>
					<artifactId>maven-source-plugin</artifactId>
					<executions>
						<execution>
							<goals>
								<goal>jar</goal>
							</goals>
						</execution>
					</executions>
				</plugin>
			</plugins>
		</pluginManagement>

		<plugins>
			<!-- maven-enforcer-plugin 这个插件会对项目环境进行检查 -->
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-enforcer-plugin</artifactId>
			</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.8.0</version>
				<configuration>
					<source>1.8</source>
					<target>1.8</target>
				</configuration>
			</plugin>
		</plugins>
	</build>

	<distributionManagement>
		<repository>
			<id>phoenix-releases</id>
			<url>https://repo.rdc.aliyun.com/repository/114773-release-m6CZw0/</url>
		</repository>
		<snapshotRepository>
			<id>phoenix-snapshots</id>
			<url>https://repo.rdc.aliyun.com/repository/114773-snapshot-Hz4DGO/</url>
		</snapshotRepository>
	</distributionManagement>

	<modules>
		<module>phenix-spring-boot-starter-web</module>
		<module>phenix-spring-boot-starter-logging</module>
		<module>phenix-spring-boot-starter-swagger</module>
		<module>phenix-spring-boot-starter-mysql</module>
		<module>phenix-spring-boot-starter-redis</module>
		<module>phenix-spring-boot-starter-nacos</module>
		<module>phenix-spring-boot-starter-admin</module>
        <module>phenix-spring-boot-starter-rabbitmq</module>
		<module>phenix-spring-boot-starter-mybatis-plus</module>
		<module>phenix-spring-boot-starter-feign</module>
		<module>phenix-spring-boot-starter-security</module>
		<module>phenix-spring-boot-starter-all</module>
	</modules>
</project>

为了避免需要每个包都引用,使用phenix-spring-boot-starter-all来引用所有的子starter包。也可以根据需要自行搭配。

注意:distributionManagement 需配置私有仓库地址,本文采用阿里云效的私有仓库,使用私有仓库需申请开通云效。并下载私有仓库提供的settings.xml文件,覆盖本地settings.xml。