Spring Boot multi module development and pit drainage guide none in history

Recommended reading: How to improve the core competitiveness of Java engineers who have worked for 1-5 years

                  Ali architect said: "no real combat is just talking on paper"! Redis live PDF sharing

                  Working hard for more than half a year, Ali finally got his favorite offer grade P7

Create project

It's very simple to create a Spring Boot project. It doesn't need to be mentioned at all. You can directly choose Spring initiate to create a Spring Boot project when using IDEA to create a new project, or you can use the Spring Boot project page provided by Spring to generate a project.

Here's how to use Spring official generation. If you already have a Spring Boot project, you can skip this part.

  1. Open https://start.spring.io/  

  2. Fill in the group and Artifact information and choose dependency (I chose Spring Web and Lombok).

    Create initial project on spring official website

  3. Click the Generate button to download the project.

  4. Open the downloaded project, delete the useless. mvn folder, mvnw mvnw.cmd  , HELP.md Documents.

Now that we have got an initial project of Spring Boot, let's import it into IDEA and have a look pom.xml Content of.

<?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.5.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.wdbyte</groupId>
	<artifactId>springboot-module-demo</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>springboot-module-demo</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-web</artifactId>
		</dependency>

		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<optional>true</optional>
		</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>
</project>

Adjust the directory structure to the structure you want, and then add controller and entity for testing.

Project directory structure

ProductController class source code.

@RestController
@RequestMapping("/product")
public class ProductController {

    /**
     * Get product list
     *
     * @return
     */
    @GetMapping("/list")
    public Map list() {
        // Simulation query commodity logic
        Product product = new Product();
        product.setProductName("Millet Congee");
        product.setProductPrice(new BigDecimal(2.0));
        product.setProductStock(100);

        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("code", 000);
        resultMap.put("message", "success");
        resultMap.put("data", Arrays.asList(product));
        return resultMap;
    }
}

Product class source code.

@Data
public class Product {
    /** Commodity name */
    private String productName;
    /** Commodity price */
    private BigDecimal productPrice;
    /** Merchandise inventory.*/
    private int productStock;
}

modularization

With the aid of IDEA tools, we can quickly transform the project into maven multi module. Here, we divide the demo to be tested into two modules, common and web. The common module stores entity classes. The web module stores the controller layer (although the project here is small, it's just for demonstration). Don't say much, just start.

  1. Configure master pom.xml The packing method is 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>
        <!-- Configure master pom Packing method is pom -->
        <packaging>pom</packaging>
        ....
        ....
    
  2. Create common module

    Project directly new - > module.

    Create module

    Select Maven - > next and fill in the module name.

    Fill in module name

    Continue to next to complete the module creation.

  3. Create web module

    The creation of the web module is the same as the common module, which will not be discussed in detail. After creating the two modules, you will find your master pom.xml The module section is automatically added to the file.

    <modules>
        <module>product-common</module>
    	<module>product-web</module>
    </modules>
    
  4. Move code to specified module

    Move Product.java To the product common module, the other parts of the code and resource are moved directly to the product web module. After the move, your code structure is like this.

    Multi module directory structure

At this point, multi module splitting has been completed, but the red warning in the product controller code lets you find that things are not over.

Dependency management

Dealing with dependency

You find the red warning in the code, but you also think of it in an instant because the Product class has been moved to the Product common module, resulting in the missing reference here.

Red warning

Then you look at the pom.xml The contents of.

<?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">
    <parent>
        <artifactId>springboot-module-demo</artifactId>
        <groupId>com.wdbyte</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>product-common</artifactId>
</project>

Smart in the product web module pom.xml Product common is introduced in, which is easy to handle.

<?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">
    <parent>
        <artifactId>springboot-module-demo</artifactId>
        <groupId>com.wdbyte</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>product-web</artifactId>
    <dependencies>
        <dependency>
            <groupId>com.wdbyte</groupId>
            <artifactId>product-common</artifactId>
        </dependency>
    </dependencies>
</project>

Happy you quickly click build - > Build Project, and the Error warning you get stings you with black eyes.

However, you quickly locate the problem and check the maven dependency. You find that the version number of the product common dependency is not specified.

Error message

I see. Because we didn't specify the version number, we didn't finish specifying it. In the outermost layer of the main pom.xml Add < dependencymanagement > to add the specified dependency and version number to be specified.

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>com.wdbyte</groupId>
                <artifactId>product-common</artifactId>
                <version>0.0.1-SNAPSHOT</version><!-- maven Package default 0.0.1-SNAPSHOT edition -->
            </dependency>
        </dependencies>
    </dependencyManagement>

Refresh maven, find that the project has not reported an error, compile successfully, run the startup class, and the familiar Spring logo appears in front of you.

Optimize dependencies

Yes, the Spring Boot application has been successfully run after being transformed into a multi module application, but you seem to find a problem. Both the module common and the module web inherit the main pom. The main pom includes Lombok, Spring Boot Web and Spring Boot Test dependencies, while the common module only uses Lombok, but it also inherits the Spring Boot Other dependencies, it seems, need to be transformed.

  1. Only the dependencies used by the common module are moved to the common module.

    <?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">
        <parent>
            <artifactId>springboot-module-demo</artifactId>
            <groupId>com.wdbyte</groupId>
            <version>0.0.1-SNAPSHOT</version>
        </parent>
        <modelVersion>4.0.0</modelVersion>
        <artifactId>product-common</artifactId>
        <dependencies>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <optional>true</optional>
            </dependency>
        </dependencies>
    </project>
    
  2. Only the dependencies used by the web module are moved to the web module.

    <?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">
        <parent>
            <artifactId>springboot-module-demo</artifactId>
            <groupId>com.wdbyte</groupId>
            <version>0.0.1-SNAPSHOT</version>
        </parent>
        <modelVersion>4.0.0</modelVersion>
        <artifactId>product-web</artifactId>
        
        <dependencies>
            <dependency>
                <groupId>com.wdbyte</groupId>
                <artifactId>product-common</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>
                <exclusions>
                    <exclusion>
                        <groupId>org.junit.vintage</groupId>
                        <artifactId>junit-vintage-engine</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
        </dependencies>
    </project>
    
  3. Extract the version number used to < Properties >. Extract the dependent version of the common module here.

    This is the content of the outermost main pom here.

    <?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>
        <packaging>pom</packaging>
        <modules>
            <module>product-common</module>
            <module>product-web</module>
        </modules>
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.2.5.RELEASE</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
        <groupId>com.wdbyte</groupId>
        <artifactId>springboot-module-demo</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>springboot-module-demo</name>
        <description>Demo project for Spring Boot</description>
    
        <properties>
            <java.version>1.8</java.version>
            <product-common.version>0.0.1-SNAPSHOT</product-common.version>
        </properties>
    
        <dependencyManagement>
            <dependencies>
                <dependency>
                    <groupId>com.wdbyte</groupId>
                    <artifactId>product-common</artifactId>
                    <version>${product-common.version}</version>
                </dependency>
            </dependencies>
        </dependencyManagement>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    </project>
    

It seems perfect. Build - > Build Project again. Everything is normal, running and accessing are normal.

Provider

Package and compile

Well, it's finally the last step. You feel the dawn of victory shining on your head, reflecting the dazzling light. Then there is mvn package.

[INFO] springboot-module-demo ............................. SUCCESS [  2.653 s]
[INFO] product-common ..................................... FAILURE [  2.718 s]
[INFO] product-web ........................................ SKIPPED
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 6.084 s
[INFO] Finished at: 2020-03-19T08:15:52+08:00
[INFO] Final Memory: 22M/87M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:2.2.5.RELEASE:repackage (repackage) on project product-common: Execution repackage of goal org.springframework.boot:spring-boot-m
aven-plugin:2.2.5.RELEASE:repackage failed: Unable to find main class -> [Help 1]
[ERROR]

ERROR makes you sad, but you still find some clues from the ERROR report. You see that spring boot Maven plugin reported the ERROR. Reexamine your main pom and find that spring boot Maven plugin is used in < build > compiling plug-ins.

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

After a little thought, move this section to the pom of the web module, because this is the packaging method of Spring Boot. Now all modules in the main pom will inherit to, so it is definitely not necessary for the common module.

After moving, repackage. Whether you run the command mvn package or double-click the package in maven management in IDEA, you must have successfully packed at this time

 

IDEA packaging

You can also see the packaged jar file product-web-0.0.1 in the directory target under the web module- SNAPSHOT.jar . You can run it directly using java commands.

$ springboot-module-demoproduct-webtarget>java -jar product-web-0.0.1-SNAPSHOT.jar

  .   ____          _            __ _ _
 /\ / ___'_ __ _ _(_)_ __  __ _    
( ( )___ | '_ | '_| | '_ / _` |    
 \/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |___, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.2.5.RELEASE)

2020-03-19 08:33:03.337  INFO 15324 --- [           main] com.wdbyte.Application                   : Starting Application v0.0.1-SNAPSHOT on DESKTOP-8SCFV4M with PID 15324 (C:Users83981Desktopspringboot-mod
ule-demoproduct-webtargetproduct-web-0.0.1-SNAPSHOT.jar started by 83981 in C:Users83981Desktopspringboot-module-demoproduct-webtarget)
2020-03-19 08:33:03.340  INFO 15324 --- [           main] com.wdbyte.Application                   : No active profile set, falling back to default profiles: default
2020-03-19 08:33:04.410  INFO 15324 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2020-03-19 08:33:04.432  INFO 15324 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2020-03-19 08:33:04.432  INFO 15324 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.31]
2020-03-19 08:33:04.493  INFO 15324 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2020-03-19 08:33:04.493  INFO 15324 --- [           main] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 1107 ms
2020-03-19 08:33:04.636  INFO 15324 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
2020-03-19 08:33:04.769  INFO 15324 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2020-03-19 08:33:04.772  INFO 15324 --- [           main] com.wdbyte.Application                   : Started Application in 1.924 seconds (JVM running for 2.649)
2020-03-19 08:33:07.087  INFO 15324 --- [extShutdownHook] o.s.s.concurrent.ThreadPoolTaskExecutor  : Shutting down ExecutorService 'applicationTaskExecutor'

It must be a little less. Multi module is not only for the sake of clear structure, but also for the sake of reusing modules (such as common module) for other projects. Now if you open a new project at this time, relying on common discovery cannot be referenced, because you need to install the modules in the local warehouse. You can click idea - > maven - > install, or you can use the maven command.

# - Dmaven.test.skip=true  Skip test
# -U force refresh
# Clean clean cache
# install to local warehouse
$ springboot-module-demo> mvn -Dmaven.test.skip=true -U clean install

Re introduction found no problem.

The code in this article has been uploaded to Github: NiMoO / springboot

Tags: Maven Spring Apache xml

Posted on Sat, 20 Jun 2020 04:52:25 -0400 by canadian_angel