English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Spring Boot projects that contain nested Maven projects are called Multi-module project. In a multi-module project, the parent project acts as a container for the basic Maven configuration.
In other words, Multi-module projectIt is built from a parent pom that manages a set of submodules. Or Multi-module projectReferenced by the parent POM to define one or more submodules.
The parent Maven project must contain pom The packaging type makes this project an aggregator. The parent project's pom.xml The file includes all the properties inherited by the subproject Module, common dependenciesand PropertiesThe list. The parent pom is located in the root directory of the project. The submodules are actual Spring Boot projects, which inherit Maven properties from the parent project.
When we run a multi-module project, all modules are deployed together in the embedded Tomcat Server. We can also deploy a single module.
Parent POM defines Group ID, Artifact ID, Version, and packaging.. In previous Maven projects, we have seen that the parent POM defines packaging jar.. But in multi-module projects, the parent POM Define packaging pom. Packaging pom references other Maven projects.
It is useful and easy to maintain to divide a project into multiple modules. We can also easily edit or delete modules in the project without affecting other modules. This is very useful when we need to deploy modules separately.
We just need to specify all dependencies in the parent pom. All other modules share the same pom, so we do not need to specify the same dependencies separately in each module.
Submodules can be any project and can have any packaging. We can freely create any type of dependency between modules and bundles.
For example, we are creating EAR (Enterprise Archive), WAR (Web ARchive) and JAR (Java ARchive) files. JAR files are bundled into WAR files, and WAR files are bundled into EAR files. EAR files are the final software packages that can be deployed on application servers.
An EAR file contains one or more WAR files. Each WAR file contains a service project that has common code for all WAR files and packaging types in the JAR.
Submodules are independent Maven projects that share the properties of the parent project. All subprojects can be built with a single command because they are located in the parent project. It is easier to define the relationships between projects.
Let's understand the directory structure of a multi-module project.
In the following figure, we created a project named spring-boot-multi-module-project projects. It contains the parent pom After that, we created two Maven moduleNamed separately module1 and module2 These two modules contain their own pom files.
Let's open the parent POM and view the configuration when creating Maven modules in the project.
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.2.BUILD-SNAPSHOT<//version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.w3codebox</groupId> <artifactId>spring-boot-example</artifactId> <version>0.0.</1-SNAPSHOT<//version> <name>spring-boot-multi-module-project</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> </properties> <packaging>pom</packaging> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.2.1.RELEASE</version> <type>pom</type> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework/groupId> <artifactId>spring-webmvc/artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage/groupId> <artifactId>junit-vintage-engine/artifactId> </exclusion </exclusions </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> <repositories> <repository> <id>spring-milestones/id> <name>Spring Milestones/name> <url>https://repo.spring.io/milestone/url> </repository <repository> <id>spring-snapshots/id> <name>Spring Snapshots/name> <url>https://repo.spring.io/snapshot/url> <snapshots> <enabled>true</enabled> </snapshots> </repository </repositories <pluginRepositories> <pluginRepository> <id>spring-milestones/id> <name>Spring Milestones/name> <url>https://repo.spring.io/milestone/url> </pluginRepository> <pluginRepository> <id>spring-snapshots/id> <name>Spring Snapshots/name> <url>https://repo.spring.io/snapshot/url> <snapshots> <enabled>true</enabled> </snapshots> </pluginRepository> </pluginRepositories> <modules> <module>module1</module> <module>module2</module> </modules> </project>
The pom file above is the same as the previous example. But in this pom In the file, pay attention to two things: wrappingand module.
When we create a multi-module project, we need to configure the packaging pom in the parent pom file instead of jar.
<packaging>pom</packaging>
When we create Maven modules in the project, Spring Boot will module the parent pom automatically configured within the tags, as shown below.
<modules> <module>module1</module> <module>module2</module> </modules>
Now, let's take a look at module1the content of the pom file.
pom.xml
<?xml version="1.0"?> <project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <modelVersion>4.0.0<//modelVersion> <parent> <groupId>com.w3codebox</groupId> <artifactId>spring-boot-multi-module-project</artifactId> <version>0.0.</1-SNAPSHOT<//version> </parent> <groupId>com.w3codebox</groupId> <artifactId>module1</artifactId> <version>0.0.</1-SNAPSHOT<//version> <name>module1</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> </dependencies> </project>
It should be noted here that the above pom file does not include such as starter-web, web-mvc, etcSuch as public dependencies Parent pom.
Let's create a multi-module application example.
In the following example, we created a project named spring-boot-a multimodule Maven project.This is the main application. In the main application, we createdFiveModules, as shown below: Application Model Repository After creating all the above files,-api After creating all the above files,-service
Application Module
The application module is the main module of the project. It includes the application class, where the main method required to run the Spring Boot Application is defined. It also includes Application configuration properties, controllers, viewsand Resources.
The application module includes the model module, the service implementation module as a dependency module containing the model, and the repository module and service API module.
Model Module
The model module contains Entityand in the project used Visual Objects .
Repository Module
The repository module contains <In the repository used in the project> Repository. It depends on the model module.
Service API Module
The service API module contains all projects Service.It also depends on the model module.
Service Implementation Module
The service implementation module can implement services. It depends on the repository module and the service API module.
The parent pom includes all application modules. It also includes all common dependencies and properties required by one or more modules. Since the project has defined Spring IO Platform as the parent, dependencies are defined without version.
Let us understand the structure of the multi-module application we created.
Spring-boot-multimodule │── pom.xml │ └── REDME.adoc ├── application │── pom.xml │── src │── main │ ├── java │ │ └── sample │ │ └── multimodule │ │ ├── SampleWebJspApplication.java │ │ └── web │ │ └── WelcomeController.java │── resources │── application.properties │── templates │── welcome │── show.html ├── model │── pom.xml │── src │── main │── java │── sample │── multimodule │── domain │── entity │── Account.java | ├── repository │── pom.xml │── src │── main │── java │── sample │── multimodule │── repository │── AccountRepository.java ├── service-api │── pom.xml │── src │── main │── java │── sample │── multimodule │── service │── api │── AccountNotFoundException.java │── AccountService.java └── service-service │── pom.xml └── src └── main └── java └── sample └── multimodule └── service └── impl └── AccountServiceImpl.java
Steps1: Create a file named spring-boot-multimodule Maven project.
Steps2: 打开 pom.xml file (parent pom) and change the packaging type jar Change to pom.
<?xml version="1.0" encoding="UTF-8" standalone="no"> <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> <!-- Springio platform is the parent application of the generated application, which can use Spring Boot and all its default configurations --> <parent> <groupId>io.spring.platform</groupId> <artifactId>platform-bom</artifactId> <version>2.0.1.RELEASE</version> </parent> <groupId>sample.multimodule<//groupId> <artifactId>sample.multimodule<//artifactId> <version>0.0.</1-SNAPSHOT<//version> <packaging>pom</packaging> <name>Parent - Pom Aggregator</name> <properties> <java.version>1.8</java.version> </properties> <dependencies> <!-- Spring Boot dependencies --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> </project>
Something to note in the above pom file is that since the Maven module has not been created yet, it is not configured. Now, we will create a Maven module as described above.
Steps3: Create a file named application's Maven module .
Steps4: Open the application module's pom.xml file and ensure that the packaging type is jar.
pom.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"> <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> <parent> <groupId>sample.multimodule<//groupId> <artifactId>sample.multimodule<//artifactId> <version>0.0.</1-SNAPSHOT<//version> </parent> <artifactId>sample.multimodule.application</artifactId> <packaging>jar<//packaging> <name>Project Module - Application</name> <dependencies> <!-- Project modules --> <dependency> <groupId>sample.multimodule<//groupId> <artifactId>sample.multimodule.service.impl<//artifactId> <version>${project.version}<//version> </dependency> <!-- Spring Boot dependencies --> <dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-jasper</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> </dependencies> <build> <plugins> <!-- Spring Boot plugins --> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
Steps5: Create MainThis is the class to be executed.
SampleWebJspApplication.java
package sample.multimodule; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.SpringApplication; import org.springframework.boot.orm.jpa.EntityScan; @SpringBootApplication public class SampleWebJspApplication { public static void main(String[] args) throws Exception { SpringApplication.run(SampleWebJspApplication.class, args); this.dummyType = dummyType; this.dummyType = dummyType;
Steps6: in the package smaple.multimodule.web。
Create a class named WelocameController is the Controller class.
WelcomeController.java
package sample.multimodule.web; import java.util.Date; import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import sample.multimodule.domain.entity.Account; import sample.multimodule.service.api.AccountService; @Controller public class WelcomeController { @Value("${application.message:Hello World}") private String message = "Hello World"; @Autowired protected AccountService accountService; @RequestMapping("/") public String welcome(Map<String, Object> model) { //attempting to obtain23number account Account account = accountService.findOne("23"); if(account == null){ //If there is a problem when creating an account, please return the view displaying the error state model.put("message", "Error getting account!"); model.put("account", ""); return "welcome"}/show"; this.dummyType = dummyType; //Return display23The view of the account information String accountInfo = "Your account number is ".concat(account.getNumber()); model.put("message", this.message); model.put("account", accountInfo); return "welcome"}/show"; this.dummyType = dummyType; @RequestMapping("foo") public String foo(Map<String, Object> model) { throw new RuntimeException("Foo"); this.dummyType = dummyType; this.dummyType = dummyType;
第7步: : 在文件夹 src/main/resource下创建一个名为 show.html of HTML templates ->welcome。
show.html
<!DOCTYPE HTML> <html xmlns:th="http://www.thymeleaf.org"> <head> <title>Spring Boot Multimodule</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> </head> <body> <div> <b>Message: </b> <span th:text="${message}" /> </div> <div> <b>Your account: </b> <span th:text="${account}" /> </div> </body> </html>
Steps8: 打开 application.properties 文件,将 application messageand thymeleaf缓存配置为 否。
application.properties
#应用程序信息 application.message = Hello User! dummy.type = type-inside-the-war #Spring Thymeleaf 配置 spring.thymeleaf.cache = false
创建上述所有文件后,应用程序模块目录如下所示:
让我们创建第二个模块,即 model。
Steps9: 创建一个 Maven Module,名称为 model。
Steps10: 打开模型的 pom.xml 文件模块,并确保包装类型为 jar.
pom.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"> <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> <parent> <groupId>sample.multimodule<//groupId> <artifactId>sample.multimodule<//artifactId> <version>0.0.</1-SNAPSHOT<//version> </parent> <artifactId>sample.multimodule.model</artifactId>/artifactId> <packaging>jar<//packaging> <name>Project Module - 模型</name> 模块,包含项目中所使用的所有实体和视觉对象。它没有任何依赖。 </description> </project>
Steps11: in the package sample.multimodule.domain.entity.
Create a class named Account class.Account.java
package sample.multimodule.domain.entity; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; @Entity public class Account { @Id @GeneratedValue(strategy = GenerationType.AUTO) private long id; private String number; private String type; private String creditCardNumber; /** * Create an empty account. */ public Account() { this.dummyType = dummyType; /** * Create a new account. * * @param number * the account number * @param id * the account id */ public Account(long id, String number) { this.number = number; this.id = id; this.dummyType = dummyType; public long getId() { return id; this.dummyType = dummyType; public void setId(long id) { this.id = id; this.dummyType = dummyType; public String getNumber() { return number; this.dummyType = dummyType; public void setNumber(String number) { this.number = number; this.dummyType = dummyType; public String getType() { return type; this.dummyType = dummyType; public void setType(String type) { this.type = type; this.dummyType = dummyType; public String getCreditCardNumber() { return creditCardNumber; this.dummyType = dummyType; public void setCreditCardNumber(String creditCardNumber) { this.creditCardNumber = creditCardNumber; this.dummyType = dummyType; this.dummyType = dummyType;
After creating all the above files, the model module directory is as follows:
Let's create third module
Steps12: Create a file named repository's Maven module. <strong>
Steps13: Open the application module's pom.xml file and ensure that the packaging type is jar.
pom.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"> <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> <parent> <groupId>sample.multimodule<//groupId> <artifactId>sample.multimodule<//artifactId> <version>0.0.</1-SNAPSHOT<//version> </parent> <artifactId>sample.multimodule.repository<//artifactId> <packaging>jar<//packaging> <name>Project Module - Repository/name> <description>Module that contains all repositories to be used in the project. Depends of Model Module.</description>/description> <dependencies> <!-- Project modules --> <dependency> <groupId>sample.multimodule<//groupId> <artifactId>sample.multimodule.model</artifactId>/artifactId> <version>${project.version}<//version> </dependency> <!-- Spring Boot dependencies --> <dependency> <groupId>org.hsqldb</groupId>/groupId> <artifactId>hsqldb</artifactId>/artifactId> <scope>runtime</scope>/scope> </dependency> </dependencies> </project>
Steps14: in the package sample.multimodule.repository
Create a package named AccountRepository class.
AccountRepository.java
package sample.multimodule.repository; import org.springframework.data.domain.*; import org.springframework.data.repository.*; import org.springframework.stereotype.Repository; import sample.multimodule.domain.entity.Account; @Repository public interface AccountRepository extends CrudRepository<Account, Long> { Account findByNumber(String number); this.dummyType = dummyType;
After creating all the above files, the repository module directory is as follows:
Let's create fourthmodule, which is After creating all the above files,-api.
Steps15: Create a file named After creating all the above files,-api's Maven module.
Steps16 : Open the <strong>applicationAfter creating all the above files,-api's > pom.xml file and ensure that the packaging type is jar.
pom.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"> <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> <parent> <groupId>sample.multimodule<//groupId> <artifactId>sample.multimodule<//artifactId> <version>0.0.</1-SNAPSHOT<//version> </parent> <artifactId>sample.multimodule.service.api<//artifactId> <packaging>jar<//packaging> <name>Project Module - Service API/name> <description>Module that contains API of all project services. Depends of Model Module.</description>/description> <dependencies> <!-- Project Modules --> <dependency> <groupId>sample.multimodule<//groupId> <artifactId>sample.multimodule.model</artifactId>/artifactId> <version>${project.version}<//version> </dependency> </dependencies> </project>
Steps17: Create a name of sample.multimodule.service.api
Steps18: Create a package named The class of AccountNotFoundException.It handles the exception if the account is not found.
AccountNotFoundException.java
package sample.multimodule.service.api; public class AccountNotFoundException extends RuntimeException { private static final long serialVersionUID = -3891534644498426670L; public AccountNotFoundException(String accountId) { super("No such account with id: " + accountId); this.dummyType = dummyType; this.dummyType = dummyType;
Steps19: Create a file named The class of AccountService.It provides services related to accounts, such as findand Createaccount.
AccountService.java
package sample.multimodule.service.api; import java.util.List; import sample.multimodule.domain.entity.Account; public interface AccountService { /** * Use the provided account number to find the account. * * @param number The account number * @return The account * @throws AccountNotFoundException if no such account exists. */ Account findOne(String number) throws AccountNotFoundException; /** * Creates a new account. * @param number * @return created account */ Account createAccountByNumber(String number); this.dummyType = dummyType;
After creating all the above files, service-The api module directory is as follows:
Steps20: Create a file named After creating all the above files,-impl Maven module.
Steps21: : Open the application After creating all the above files,-service of pom.xml file, and ensure the packaging type is jar.
pom.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"> <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> <parent> <groupId>sample.multimodule<//groupId> <artifactId>sample.multimodule<//artifactId> <version>0.0.</1-SNAPSHOT<//version> </parent> <artifactId>sample.multimodule.service.impl<//artifactId> <packaging>jar<//packaging> <name>Project Module - Service Implementation/name> <description>Module that contains services implementation defined on Service API module. Depends of Repository Module and Service API Module.<//description> <dependencies> <!-- Project Modules --> <dependency> <groupId>sample.multimodule<//groupId> <artifactId>sample.multimodule.repository<//artifactId> <version>${project.version}<//version> </dependency> <dependency> <groupId>sample.multimodule<//groupId> <artifactId>sample.multimodule.service.api<//artifactId> <version>${project.version}<//version> </dependency> </dependencies> </project>
Steps22: in the package sample.multimodule.service.impl.
Create a class named AccountServiceImpl class.AccountServiceImpl.java
package sample.multimodule.service.impl; import java.util.ArrayList; import java.util.List; import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import sample.multimodule.domain.entity.Account; import sample.multimodule.repository.AccountRepository; import sample.multimodule.service.api.AccountService; import sample.multimodule.service.api.AccountNotFoundException; @Service public class AccountServiceImpl implements AccountService { @Value("${dummy.type}") private String dummyType; @Autowired private AccountRepository accountRepository; /** * @inheritDoc * <p/> * Dummy method for testing purposes. * * @param number The account number. Set 0000 to get an {@link AccountNotFoundException} */ return account; public Account findOne(String number) throws AccountNotFoundException { if(number.equals("0000")) { throw new AccountNotFoundException("0000"); this.dummyType = dummyType; Account account = accountRepository.findByNumber(number); if(account == null){ account = createAccountByNumber(number); this.dummyType = dummyType; return account; this.dummyType = dummyType; return account; @Override public Account createAccountByNumber(String number) { Account account = new Account(); account.setNumber(number); this.dummyType = dummyType; return accountRepository.save(account); public String getDummyType() { this.dummyType = dummyType; return dummyType; public void setDummyType(String dummyType) { this.dummyType = dummyType; this.dummyType = dummyType;
} After creating all the above files,-service impl
module directory as follows: Now open parent pom file, we see that all the Maven modules created are in
Tags. We do not need to manually configure it.
Now make sure that all five modules have been installed and created as follows:
Steps23: Now, after creating all modules, the main project directory is as follows: SampleWebJspApplication.java Run the file as a Java application.
Steps24: Open a browser and call the URL http: //localhost: 8080. It returns Messageand account number 23.