如何为微服务构建自定义 Spring Boot Starter

x33g5p2x  于2021-10-16 转载在 Spring  
字(8.5k)|赞(0)|评价(0)|浏览(394)

概述

Spring Boot 提供父 POM,以便更轻松地创建 Spring Boot 应用程序。然而,并不是每个人都喜欢继承 spring-boot-starter-parent POM。

在我之前工作过的一个项目中,我们使用了一个自定义 Spring Boot Starter,其中包含创建微服务所需的所有安全配置和通用组件。

通过使用这个启动器,我们能够只关注服务的业务用例,而不是花时间为新的服务实现一遍又一遍地配置相同的东西

像这样,您可能有自己需要使用的公司标准父级,或者您可能只是更喜欢显式声明所有 Maven 配置。

在本教程中,我们将演示如何使用多个身份验证配置文件和默认 application.properties 构建自定义 Spring Boot Starter。

到目前为止,我们已经在之前的文章中实现了以下内容

  1. Spring Boot REST API
  2. Swagger 2 集成
  3. 基本认证和授权
  4. JWT认证授权
  5. LDAP 认证和授权
  6. noauth 配置文件禁用 Spring Security

为了实现具有上述所有功能的新微服务,我们不需要复制我们目前开发的代码here。如果这样做,会导致代码冗余,维护起来也很困难。

我们将创建一个启动模块并将所有安全配置和 application.propertiesproduct REST API 移动到启动模块。这样,新的微服务就可以从 starter 模块继承所有常见的配置/功能和应用程序属性。

为了实现这一点,我们将创建:

  1. microservice-spring-boot-starter 模块,它使用 Spring Boot Starter Parent 并在 pom.xml 中定义所需的依赖项。除此之外,它还包含所有安全配置和默认应用程序属性。
  2. microservice-starter-parent 模块,它有父 POM。父项目的打包类型应始终为 POM。那么只有我们才能在实际应用程序中将其用作父项。该父模块将启动模块定义为 pom.xmldependencyManagement 部分中的依赖项。
  3. microservice 通过父 POM 使用 starter 模块。

###命名约定

自定义启动模块不应以 Spring Boot 启动。使用 name-spring-boot-starter 作为指导。在我们的例子中,我们将启动器命名为 microservice-spring-boot-starter

让我们开始吧

我们将创建一个 Spring Boot 多模块项目,如下图所示

创建启动模块

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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
		<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.2.6.RELEASE</version>
		<relativePath /> <!-- lookup parent from repository -->
	</parent>
	
	<groupId>com.javachinna</groupId>
	<artifactId>microservice-spring-boot-starter</artifactId>
	<version>1.0</version>
	<name>microservice-spring-boot-starter</name>
	<description>Microservice Spring Boot Starter</description>
	<packaging>jar</packaging>
	<properties>
		<java.version>11</java.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-jpa</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-security</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<exclusions>
				<exclusion>
					<groupId>org.junit.vintage</groupId>
					<artifactId>junit-vintage-engine</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
		<dependency>
			<groupId>org.springframework.security</groupId>
			<artifactId>spring-security-test</artifactId>
		</dependency>
		<dependency>
			<groupId>io.springfox</groupId>
			<artifactId>springfox-swagger2</artifactId>
			<version>2.9.2</version>
		</dependency>
		<dependency>
			<groupId>io.springfox</groupId>
			<artifactId>springfox-swagger-ui</artifactId>
			<version>2.9.2</version>
		</dependency>
		<dependency>
			<groupId>io.jsonwebtoken</groupId>
			<artifactId>jjwt</artifactId>
			<version>0.9.1</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.ldap</groupId>
			<artifactId>spring-ldap-core</artifactId>
			<exclusions>
				<exclusion>
					<groupId>org.springframework</groupId>
					<artifactId>spring-beans</artifactId>
				</exclusion>
				<exclusion>
					<groupId>org.springframework</groupId>
					<artifactId>spring-tx</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
		<dependency>
			<groupId>org.springframework.security</groupId>
			<artifactId>spring-security-ldap</artifactId>
		</dependency>
		<dependency>
			<groupId>com.unboundid</groupId>
			<artifactId>unboundid-ldapsdk</artifactId>
		</dependency>
	</dependencies>
</project>

我们已经从 spring-ldap-core 依赖项中排除了 spring-beansspring-tx 依赖项,以避免版本冲突。

**注意:**如果您根本不想继承 spring-boot-starter-parent,那么您仍然可以通过删除父配置并在其中添加 spring-boot-dependencies 来使用依赖管理而不继承它pom.xmldependencyManagement 部分如下所示

<dependencyManagement>
    <dependencies>
        <dependency>
            <!-- Import dependency management from Spring Boot -->
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>2.2.6.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>
项目结构

下面显示的所有文件均从产品 REST API 项目 here 中提取。它具有所有安全配置和通用组件。任何其他通用功能(如验证)都可以添加到 starter 中,并在所有使用此 starter 的微服务中使用。

使用 Maven 安装 Starter

在启动项目中运行 mvn clean install 命令以构建 jar 并将其安装在本地 maven 存储库中。这样,当您构建父模块和子模块时,它将从本地存储库中提取。

创建父模块

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.javachinna</groupId>
	<artifactId>microservice-starter-parent</artifactId>
	<version>1.0</version>
	<packaging>pom</packaging>

	<name>microservice-starter-parent</name>
	<url>http://maven.apache.org</url>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	</properties>

	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>com.javachinna</groupId>
				<artifactId>microservice-spring-boot-starter</artifactId>
				<version>1.0</version>
			</dependency>
		</dependencies>
	</dependencyManagement>
</project>
使用 Maven 安装父级

在父项目中运行 mvn clean install 命令以将其安装到本地 Maven 存储库中。这样,当您构建子模块时,它将从本地存储库中提取。

创建微服务

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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>com.javachinna</groupId>
		<artifactId>microservice-starter-parent</artifactId>
		<version>1.0</version>
		<relativePath /> <!-- lookup parent from repository -->
	</parent>
	<artifactId>spring-boot-microservice</artifactId>
	<name>spring-boot-microservice</name>
	<description>Demo project for Spring Boot REST API CRUD Operations with Swagger Documentation</description>

	<properties>
		<java.version>11</java.version>
		<maven.compiler.source>11</maven.compiler.source>
		<maven.compiler.target>11</maven.compiler.target>
	</properties>

	<dependencies>
		<dependency>
			<groupId>com.javachinna</groupId>
			<artifactId>microservice-spring-boot-starter</artifactId>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
				<version>2.2.6.RELEASE</version>
			</plugin>
		</plugins>
	</build>

</project>

由于我们使用的是自定义父级,因此我们不会获得 spring-boot-starter-parent 提供的插件管理功能。这就是我们添加带有版本号的 spring-boot-maven-plugin 的原因。

我们在 starter 模块本身中添加了所有微服务通用的依赖项。除此之外,如果需要任何特定于服务的依赖项,则应将它们添加到微服务 pom 本身中。

项目结构

下面显示的所有文件均从产品 REST API 项目 here 中提取。它只有特定于产品的类,将所有通用配置保留在入门模块中

继承 application.properties

默认情况下,属性将从以下位置的 application.properties 和/或 application.yml 文件加载:

  • file:./config/
  • file:./
  • classpath:config/
  • classpath:

该列表按优先级排序(在列表中较高位置定义的属性覆盖在较低位置定义的属性)。

因此,我们已将 application.properties 移动到 starter 模块中的资源文件夹

相关文章