请参见官方文档Spring指南之创建多模块项目 参见项目地址
文章目录
- 一.简介
- 二.你将创造什么(What You Will Build)
- 三.Create a Root Project(创建根目录)
- 3.1 Create the Directory Structure(创建目录结构)
- 3.2 使用idea搭建
- 四.Create the Library Project(创建library项目)
- 4.1 创建目录结构
- 4.2 Setting up the Library Project(建立Library项目)
- 4.3 Create a Service Component(创建服务组件)
- 4.3 Testing the Service Component(测试服务组件)
- 4.4 测试中报错问题
- 五.Create the Application Project(创建应用程序项目)
- 5.1 Setting up the Application Project(设置应用程序项目)
- 5.2 Write the Application(编写应用程序)
- 5.3 @SpringBootApplication注解讲解
- 5.4 测试报错问题及解决方法
一.简介
本指南向您展示了如何使用Spring Boot创建多模块项目(a multi-module project)。该项目将有一个 library jar和一个使用 library 的主应用程序(main application)。您还可以使用它来了解如何独立构建一个 library(一个不是应用程序的jar文件)。
二.你将创造什么(What You Will Build)
您将设置一个 library jar,它为简单的“Hello, World”消息公开一个服务,然后将该服务包含在一个将 library 用作依赖项的web应用程序中。You will set up a library jar that exposes a service for simple “Hello, World” messages and then include the service in a web application that uses the library as a dependency.
三.Create a Root Project(创建根目录)
本指南将介绍如何构建两个项目,其中一个是对另一个的依赖。因此,您需要在根项目下创建两个子项目。但是首先在顶层创建构建配置(But first, create the build configuration at the top level)。对于Maven,你会想要一个带有 modules 标签的 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">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mashirro</groupId>
<artifactId>gs-multi-module</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>library</module>
<module>application</module>
</modules>
</project>
3.1 Create the Directory Structure(创建目录结构)
在你想要作为根目录的目录下,创建以下子目录结构。在项目的根目录中,您将需要设置一个构建系统(you will need to set up a build system),本指南将向您展示如何使用Maven。
└── library
└── application
3.2 使用idea搭建
1.File-new-project-选择maven-next-输入groupid和artifactid-next-finish
四.Create the Library Project(创建library项目)
两个项目中的一个作为另一个项目(应用程序)将使用的库(One of the two projects serves as a library that the other project (the application) will use)。
4.1 创建目录结构
1.现在您需要配置一个构建工具(比如 Maven)。请注意,在 library 项目中根本没有使用Spring Boot Maven插件。这个插件的主要功能是创建一个可执行文件“über-jar”,我们既不需要也不想要它作为一个库(which we neither need nor want for a library)。虽然没有使用Spring Boot Maven插件,但你确实想利用Spring Boot依赖项管理的优势,因此可以使用Spring Boot的spring-boot-starter-parent作为父项目来配置它。另一种方法是在 pom.xml 文件的dependencyManagement 部分将依赖项管理作为物料清单(BOM)导入。
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencyManagement>
<dependencies>
<dependency>
<!-- Import dependency management from Spring Boot -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.6.4</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
4.2 Setting up the Library Project(建立Library项目)
对于Library项目,您不需要添加依赖项。基本的spring-boot-starter依赖项提供了所需的一切。
1.父项目gsmultimodule右键-new-module-选择Spring Initializr-next-填写group和artifact-next-不选择依赖-next-finish。
<?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.6.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.mashirro</groupId>
<artifactId>library</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>library</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2.调整 Library 项目
(1)如果您从start.spring.io生成了Library项目,它将包含一个用于构建系统的包装器脚本(mvnw或gradlew,取决于您的选择)。你可以把这个脚本和它的相关配置移动到根目录:
$ mv mvnw* .mvn ..
$ mv gradlew* gradle ..
(2)Library项目没有带有 main 方法的类(因为它不是一个应用程序)。因此,您必须告诉构建系统不要尝试为Library项目构建一个可执行jar。(默认情况下,Spring Initializr构建可执行项目)。要告诉Maven不要为Library项目构建一个可执行jar文件,你必须从Spring Initializr创建的pom.xml文件中删除以下代码块:
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
4.3 Create a Service Component(创建服务组件)
library 将提供一个MyService类,供应用程序使用。
@Service
@EnableConfigurationProperties(ServiceProperties.class)
public class MyService {
private final ServiceProperties serviceProperties;
public MyService(ServiceProperties serviceProperties) {
this.serviceProperties = serviceProperties;
}
public String message() {
return this.serviceProperties.getMessage();
}
}
要使它在标准的Spring Boot习惯用法(使用application.properties)中可配置,还可以添加一个@ConfigurationProperties类。
@ConfigurationProperties("service")
public class ServiceProperties {
private String message;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
4.3 Testing the Service Component(测试服务组件)
1.您可能需要为 library 组件编写单元测试。如果您提供可重用的Spring配置作为 library 的一部分,您可能还想编写一个集成测试,以确保配置工作。为此,您可以使用JUnit和@SpringBootTest注释。
@SpringBootTest("service.message=Hello")
class LibraryApplicationTests {
@Autowired
private MyService myService;
@Test
void contextLoads() {
System.out.println(myService.message());
}
}
2.使用@SpringBootTest注释的默认属性为测试配置 service.message 。我们不建议将 application.properties 放入 library,因为在运行时可能会与使用 library 的应用程序发生冲突(从类路径仅加载一个application.properties)。你可以把 application.properties 放在测试类路径中,但不将其包含在jar中(例如,将其放在src/test/resources中)。
4.4 测试中报错问题
1.比如我把 library 的启动类LibraryApplication删除。然后再运行单元测试。会报以下错误:
java.lang.IllegalStateException: Unable to find a @SpringBootConfiguration,
you need to use @ContextConfiguration or @SpringBootTest(classes=...) with your test
2.两种解决方法:(1)是保留启动类(2)是在单元测试中添加以下代码:
//注解+static
@SpringBootApplication
static class TestConfiguration {
}
五.Create the Application Project(创建应用程序项目)
应用程序项目使用Library项目,Library项目提供了其他项目可以使用的服务。
5.1 Setting up the Application Project(设置应用程序项目)
1.对于Application项目,您需要Spring Web和Spring Boot Actuator依赖项。
<?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.6.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.mashirro</groupId>
<artifactId>application</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>application</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</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-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2.Adding the Library Dependency(添加Library依赖)
<dependency>
<groupId>com.mashirro</groupId>
<artifactId>library</artifactId>
<version>${project.version}</version>
</dependency>
5.2 Write the Application(编写应用程序)
1.编写 MyController
@RestController
public class MyController {
private final MyService myService;
public MyController(MyService myService) {
this.myService = myService;
}
@GetMapping("/")
public String home() {
return myService.message();
}
}
2.创建application.properties文件
您需要在application.properties中为 Library 中的服务提供一条消息。在源文件夹中,您需要创建一个名为src/main/resources/application.properties的文件。
service.message=Hello, World
5.3 @SpringBootApplication注解讲解
1.@SpringBootApplication是一个方便的注释,它添加了以下所有内容:
- @Configuration:将类标记为应用程序上下文的bean定义源。
- @EnableAutoConfiguration:告诉Spring Boot根据类路径设置、其他bean和各种属性设置开始添加bean。例如,如果spring-webmvc在类路径上,这个注释将该应用标记为一个web应用程序,并激活关键行为,比如设置一个DispatcherServlet。
- @ComponentScan:告诉Spring在xxx包中寻找其他组件、配置和服务,让它找到控制器。
5.4 测试报错问题及解决方法
1.通过启动 Application 来测试端到端结果。可以在IDE中启动应用程序,也可以使用命令行。应用程序运行后,请访问浏览器中的客户端应用程序,网址为http://localhost:8080/。报错信息如下
***************************
APPLICATION FAILED TO START
***************************
Description:
Parameter 0 of constructor in com.mashirro.application.controller.MyController
required a bean of type 'com.mashirro.library.service.MyService' that could not be found.
2.因为Application(com.mashirro.application包)和MyService(com.mashirro.library.service包)是在不同的包中,所以@SpringBootApplication不能自动检测到它。有几种不同的方法可以让“MyService”被选中:
- 直接用@Import(MyService.class)导入它。
- 使用@SpringBootApplication(scanBasePackageClasses={…})从它的包中获取所有内容。
- 通过名称指定父包:com.mashirro。(本指南使用此方法)
@SpringBootApplication(scanBasePackages = "com.mashirro")
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
3.其实还有一种方法:那就是直接把application项目的启动类挪到父包:com.mashirro下即可!!