在gitee上查找资料的时候,发现有不少Springboot项目里边都是嵌套了多个Springboot项目的。这个玩意好,在协作开发的时候,将项目分成多个模块,有多个团队协作开发,模块间定义标准化通信接口进行数据交互即可。
这个好这个。我之前创建的博客项目是单模块的SpringBoot项目,那我创建一个多模块的SpringBoot项目来将我的博客改成多模块项目。正好后边可以用这个尝试下微服务。
下边记录一下SpringBoot多模块项目的创建流程
一:创建父工程
首先我们先在IDEA中创建一个父项目,使用Maven托管。如下图所示:
点击下一步,不需要添加任何依赖,点击创建完成即可。
项目创建成功如下图所示:
删除图上红框标注的所有文件,只保留pom.xml
二:创建Utils子模块
这个跟创建父工程的流程是一样的,唯一不同的就是第一步,如下图所示:
建议创建子模块的包名是一致的,我这里使用的包名是:com.modules
子模块创建成功之后,我们配置一下子模块的pom.xml使其成为父工程的子工程。
在子工程pom.xml中添加
<!-- 配置父工程 -->
<parent>
<groupId>com.modules</groupId>
<artifactId>NacosProject</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
如下图所示:
接着在父工程的pom.xml中配置:
<!--将子模块放在一堆 start -->
<modules>
<module>NacosUtils</module>
</modules>
<!--将子模块放在一堆 end -->
因为我这里创建的utils子模块只存储以后项目中需要的公共的utils公共文件,因此不需要启动类,也就不需要配置resources下方的application.properties文件。如下图所示:
删除成功之后,我们在com.modules.nacosutils目录下创建Utiils.java文件:
package com.modules.nacosutils;
public class Utils
{
public static void utils()
{
System.out.println("我是NacosUtils项目中的Utils类的utils方法");
}
}
这个项目创建到这里即可,接下来我们继续创建其他子项目。
三:创建service子模块
创建NacosService子模块。具体参照NacosUtils创建截图,这里不再赘述。
配置方式跟NacosUtils方式一致。
在NacosService项目中的pom.xml中添加父项目信息:
<!-- 配置父工程 -->
<parent>
<groupId>com.modules</groupId>
<artifactId>NacosProject</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
添加对NacosUtils项目的依赖:
<dependency>
<groupId>com.modules</groupId>
<artifactId>NacosUtils</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
在父项目的pom.xml中添加子项目信息:
<!--将子模块放在一堆 start -->
<modules>
<module>NacosUtils</module>
<module>NacosService</module>
</modules>
<!--将子模块放在一堆 end -->
NacosService模块主要存放三层架构中的service逻辑层,主要用来处理逻辑,因此这里也不需要启动类以及resources下方的application.properties文件,删除。
在com.modules.nacosservice目录下创建nacosService.java文件
package com.modules.nacosservice;
import com.modules.nacosutils.Utils;
import org.springframework.stereotype.Service;
@Service
public class nacosService
{
public void nacos()
{
// 调用 NacosUtils项目下的Utils类
Utils.utils();
System.out.println("我是NacosService项目中的nacos方法");
}
}
这个模块先创建到这里
四:创建controller子模块
创建NacosController子模块。具体参照NacosUtils创建截图,这里不再赘述。
在NacosController项目中的pom.xml中添加父项目信息:
<!-- 配置父工程 -->
<parent>
<groupId>com.modules</groupId>
<artifactId>NacosProject</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
添加对NacosService项目的依赖:
<dependency>
<groupId>com.modules</groupId>
<artifactId>NacosService</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
在父项目的pom.xml中添加子项目信息:
<!--将子模块放在一堆 start -->
<modules>
<module>NacosUtils</module>
<module>NacosService</module>
<module>NacosController</module>
</modules>
<!--将子模块放在一堆 end -->
NacosController模块主要存放三层架构中的controller控制器层,主要用来接收前端访问,因此这里也不需要启动类以及resources下方的application.properties文件,删除。
在com.modules.nacoscontroller目录下创建HelloController.java文件
package com.modules.nacoscontroller;
import com.modules.nacosservice.NacosService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
@RestController
public class HelloController
{
@Resource
private NacosService nacosService;
@GetMapping("/hello")
public void nacos()
{
nacosService.nacos();
}
}
controller模块创建到这里就可以了。
现在有一个小问题,我们创建了一个父项目中包含了三个子模块,都没有启动文件,那我们还需要创建一个有启动类的子模块。
五:创建entry子模块
创建NacosEntry子模块。具体参照NacosUtils创建截图,这里不再赘述。
在NacosEntry项目中的pom.xml中添加父项目信息:
<!-- 配置父工程 -->
<parent>
<groupId>com.modules</groupId>
<artifactId>NacosProject</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
添加对NacosController项目的依赖:
<dependency>
<groupId>com.modules</groupId>
<artifactId>NacosController</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
在父项目的pom.xml中添加子项目信息:
<!--将子模块放在一堆 start -->
<modules>
<module>NacosUtils</module>
<module>NacosService</module>
<module>NacosController</module>
<module>NacosEntry</module>
</modules>
<!--将子模块放在一堆 end -->
NacosEntry模块就是项目的启动模块,啥也不需要改。配置一下resources下方的application.properties文件中的项目启动端口号即可:
server.port=8085
最后,我们需要在启动类上添加扫描文件注解:
//@ComponentScan(basePackages = {"com.modules.nacoscontroller", "com.modules.nacosservice"})
@ComponentScan(basePackages = "com.modules")
上边两种写法都可以,我在上边创建子模块的时候建议大家把包名写一致就是为了这里写着方便。
完整启动类代码:
package com.modules.nacosentry;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
@SpringBootApplication
//@ComponentScan(basePackages = {"com.modules.nacoscontroller", "com.modules.nacosservice"})
@ComponentScan(basePackages = "com.modules")
public class NacosEntryApplication {
public static void main(String[] args) {
SpringApplication.run(NacosEntryApplication.class, args);
}
}
启动项目,访问http://localhost:8085/hello
浏览器输出:
控制台输出:
上面就说明我们的子模块之间可以相互调用了,到这,我们的Springboot多模块项目就搭建完成了。
六:数据库配置
1 :在application.properties配置文件中配置数据库信息
spring:
devtools:
restart:
enabled: true
additional-paths: src/main/java
# 数据库链接
datasource:
# driver-class-name: com.mysql.jdbc.Driver
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://xxxxx:3306/xxxx?serverTimezone=GMT&useSSL=false
username: root
password: xxxxxx
# 配置myBatis xml文件以及对应的到文件位置
mybatis:
mapper-locations: classpath:com.modules.dao/*.xml
type-aliases-package: com.modules.dao
2 :如果你是用的mapper注解
还需要再启动类上加上
@MapperScan(basePackages = "com.modules.dao") // 扫描数据库操作类
全部代码:
package com.modules.entry;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
@SpringBootApplication
@ComponentScan(basePackages = "com.modules")
@MapperScan(basePackages = "com.modules.dao") // 扫描数据库操作类
public class EntryApplication {
public static void main(String[] args) {
SpringApplication.run(EntryApplication.class, args);
}
}
七:多模块项目打包
然后,就有了下一个小问题,项目开发完了,该如何打包呢?
很简单,配置一下子项目中的pom.xml文件中的build项即可。
1 :配置父项目的pom.xml
(1):配置父模块打包方式:
<!-- 父模块的打包方式-->
<packaging>pom</packaging>
(2):配置java版本
<properties>
<java.version>11</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-boot.version>2.6.13</spring-boot.version>
</properties>
(3):配置子模块
<!--将子模块放在一堆 start -->
<modules>
<module>NacosUtils</module>
<module>NacosService</module>
<module>NacosController</module>
<module>NacosEntry</module>
</modules>
<!--将子模块放在一堆 end -->
(4):配置打包插件
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
<configuration>
<skipTests>true</skipTests> <!--默认关掉单元测试 -->
</configuration>
</plugin>
</plugins>
</build>
至此,父项目的pom.xml文件配置完成。
2 :配置子项目的pom.xml文件
这里要分为两种情况:
没有启动类的子模块:NacosUtils、NacosService、NacosController
有启动类的子模块:NacosEntry
(1):设置打包机制(我创建的就是jar项目,默认打包就是jar)
<packaging>jar</packaging>
(2):配置springboot版本
<properties>
<java.version>11</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-boot.version>2.6.13</spring-boot.version>
</properties>
(3):没有启动类的子模块的build配置
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>11</source>
<target>11</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<configuration> <!-- 这个标签很重要 -->
<skip>true</skip>
</configuration>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
(4):有启动类的子模块的build配置
为什么true会导致找不到主清单属性?
在spring-boot-maven-plugin的配置中设置 true 时,实际上你告诉Maven在执行构建生命周期时跳过这个插件的运行。此插件负责将你的项目打包成一个可执行的JAR文件,其中包含了一个正确的清单文件(MANIFEST.MF)以及所有的项目依赖项。
在清单文件中,主类(Main Class)的信息是一个关键的元素,它告诉JVM运行哪一个类的main方法作为程序的入口点。如果spring-boot-maven-plugin被跳过了,那么这个清单文件可能不会被正确地生成,主类的信息也就不会被加入到清单文件中。这就是为什么当你尝试运行JAR文件时,你会看到 "没有主清单属性" 的错误。
所以,为了正确生成可执行的JAR文件,需要移除 true 配置,或者将其设置为 false。这样,在执行 mvn package 或者 mvn install 时,spring-boot-maven-plugin就会被执行,它会生成一个正确的可执行的JAR文件,包含了主类的信息以及所有的项目依赖项。
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>11</source>
<target>11</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<configuration>
<mainClass>com.modules.nacosentry.NacosEntryApplication</mainClass>
<!-- 有启动类的项目带这个标签会报错:没有主清单属性 -->
<!-- <skip>true</skip>-->
</configuration>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
将每个子项目配置完成之后,我们开始在IDEA中开始打包操作。
打包先需要install一下父工程
然后再依次根据依赖执行NacosUtils项目生命周期中的install,再执行NacosService项目生命周期中的install,再执行NacosController项目生命周期中的install,最后执行NacosEntry项目生命周期中的install,至此打包成功。
我们可以在target目录下发现打包后的jar文件
测试执行一下,在当前目录下调出控制台,运行命令:
java -jar NacosEntry-0.0.1-SNAPSHOT.jar
在浏览器中访问:
发现,打包成功。
使用
Java -jar xxxxxx.jar
命令运行打包完成得jar文件。通过浏览器测试也是没有问题的。
八:整理pom.xml文件
父项目的pom.xml文件主要就是管理jar包和依赖。那么子项目中相同的依赖等就可以配置到父项目的pom.xml中,简化子项目pom.xml。
我这里展示一下完整的父项目的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>
<!-- ========================================================= -->
<!-- 父工程主要是管理jar包和依赖 -->
<!-- 父模块的打包方式-->
<packaging>pom</packaging>
<groupId>com.modules</groupId>
<artifactId>NacosProject</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>NacosProject</name>
<description>NacosProject</description>
<properties>
<java.version>11</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-boot.version>2.6.13</spring-boot.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>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</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>
</dependencies>
</dependencyManagement>
<!--将子模块放在一堆 start -->
<modules>
<module>NacosUtils</module>
<module>NacosService</module>
<module>NacosController</module>
<module>NacosEntry</module>
</modules>
<!--将子模块放在一堆 end -->
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
<configuration>
<skipTests>true</skipTests> <!--默认关掉单元测试 -->
</configuration>
</plugin>
</plugins>
</build>
</project>
子项目NacosEntry项目的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.modules</groupId>
<artifactId>NacosProject</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<packaging>jar</packaging>
<groupId>com.modules</groupId>
<artifactId>NacosEntry</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>NacosEntry</name>
<description>NacosEntry</description>
<dependencies>
<dependency>
<groupId>com.modules</groupId>
<artifactId>NacosController</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>11</source>
<target>11</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<configuration>
<mainClass>com.modules.nacosentry.NacosEntryApplication</mainClass>
<!-- 有启动类的项目带这个标签会报错:没有主清单属性 -->
<!-- <skip>true</skip>-->
</configuration>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
实例在文末,可下载。
以上大概就是Springboot多模块项目创建打包的全过程。
有好的建议,请在下方输入你的评论。