一,多模块项目的优点:

1,为什么要使用多模块项目?

相比传统的单体工程,使用Maven的多模块配置,

有如下优点:

帮助项目划分模块,鼓励重用,

防止POM变得过于庞大,

方便某个模块的构建,而不用每次都构建整个项目,

对某个模块的特殊控制更为方便

2,创建项目的流程:

先创建一个空项目multimodjar,删除无关文件,只留一个pom.xml和一个multimodjar.iml

然后在这个项目下创建module

3,pom.xml/multimodjar.iml 两个文件的用途说明:

pom.xml:  项目对象模型(Project Object Model)的简称,它是Maven项目中的文件。

作用:管理源代码/配置文件/开发者的信息和角色/问题追踪系统/组织信息/项目授权/项目的url/项目的依赖关系等

multimodjar.iml,iml文件,infomation  of  module,

作用:保存了项目的配置信息,intellij idea需要从它获取项目信息

说明:刘宏缔的架构森林是一个专注架构的博客,地址:https://www.cnblogs.com/architectforest

对应的源码可以访问这里获取: https://github.com/liuhongdi/

说明:作者:刘宏缔 邮箱: 371125307@qq.com

二,  演示项目的相关信息

1,项目地址:

https://github.com/liuhongdi/multimodjar

2,项目功能说明:

演示了多模块项目如何配置pom.xml打包

项目包含了4个模块:mmweb(可执行的入口)

mmservice

mmpojo

mmrepo(数据库)

3,项目结构:如图:

三,配置文件说明

1,根项目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.3.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.multimodjar</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description> <properties>
<java.version>11</java.version>
</properties>
<packaging>pom</packaging> <modules>
<module>mmweb</module>
<module>mmpojo</module>
<module>mmrepo</module>
<module>mmservice</module>
</modules>
</project>

可以看到,在根项目中,只需要添加对各个模块的依赖

2,mmweb模块的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.3.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.mmweb</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description> <properties>
<java.version>11</java.version>
</properties> <dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--mmservice begin-->
<dependency>
<groupId>com.mmservice</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<!--mmpojo begin-->
<dependency>
<groupId>com.mmpojo</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<!--thymeleaf begin-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</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>
<!--spring boot打包的话需要指定一个唯一的入口类-->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>com.mmweb.demo.DemoApplication</mainClass>
<layout>ZIP</layout>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

因为mmweb是可执行的类所在模块,所以需要专门指定执行mainClass入口类

3,mmweb的application.properties

#error
server.error.include-stacktrace=always
#errorlog
logging.level.org.springframework.web=trace #mysql
spring.datasource.url=jdbc:mysql://localhost:3306/store?characterEncoding=utf8&useSSL=false
spring.datasource.username=root
spring.datasource.password=lhddemo
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver #mybatis
mybatis.mapper-locations=classpath:/mapper/*Mapper.xml
mybatis.type-aliases-package=com.example.demo.mapper
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl #thymeleaf
spring.thymeleaf.cache=false
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.mode=HTML
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html

4,mmservice的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.3.3.RELEASE</version>
<relativePath/>
</parent>
<groupId>com.mmservice</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description> <properties>
<java.version>11</java.version>
</properties> <dependencies>
<!--mmpojo begin-->
<dependency>
<groupId>com.mmpojo</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<!--mmrepo begin-->
<dependency>
<groupId>com.mmrepo</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<!--pagehelper begin-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.12</version>
</dependency>
</dependencies>
</project>

5,mmrepo的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.3.3.RELEASE</version>
<relativePath/>
</parent>
<groupId>com.mmrepo</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description> <properties>
<java.version>11</java.version>
</properties> <dependencies>
<dependency>
<groupId>com.mmpojo</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!--mybatis begin-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.3</version>
</dependency>
<!--mysql begin-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
</project>

6,mmpojo的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.3.3.RELEASE</version>
<relativePath/>
</parent>
<groupId>com.mmpojo</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description> <properties>
<java.version>11</java.version>
</properties>
</project>

7,用到的数据表的结构:

CREATE TABLE `goods` (
`goodsId` int(11) NOT NULL AUTO_INCREMENT COMMENT 'id',
`goodsName` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' COMMENT 'name',
`subject` varchar(200) NOT NULL DEFAULT '' COMMENT '标题',
`price` decimal(15,2) NOT NULL DEFAULT '0.00' COMMENT '价格',
`stock` int(11) NOT NULL DEFAULT '0' COMMENT 'stock',
PRIMARY KEY (`goodsId`)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='商品表'

四,java代码说明

1,DemoApplication.java

@SpringBootApplication(scanBasePackages = {"com.mmservice.demo","com.mmpojo.demo","com.mmweb.demo"})
@MapperScan("com.mmrepo.demo")
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}

说明:因为引入了多模块,需要添加上扫描包的路径

2,HomeController.java

import com.mmpojo.demo.pojo.Goods;
import com.mmservice.demo.service.GoodsService;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*; import javax.annotation.Resource;
import java.util.List;
import java.util.Map; @Controller
@RequestMapping("/home")
public class HomeController { @Resource
private GoodsService goodsService; // list all goods
@GetMapping("/list")
@ResponseBody
public List<Goods> all() {
System.out.println("-------------------------list");
List<Goods> list = goodsService.getAllGoods();
return list;
} //带模板显示商品列表 参数:第几页
@GetMapping("/goodslist")
public String goodsList(Model model,
@RequestParam(value="p",required = false,defaultValue = "1") int currentPage) {
Map<String,Object> res = goodsService.getAllGoodsByPage(currentPage);
model.addAttribute("pageInfo", res.get("pageInfo"));
model.addAttribute("goodslist", res.get("goodslist"));
return "goods/goodslist";
}
}

注意import的goods/GoodsService类的路径

3,GoodsServiceImpl.java

@Service
public class GoodsServiceImpl implements GoodsService { @Resource
private GoodsMapper goodsMapper; //返回全部商品
@Override
public List<Goods> getAllGoods() {
List<Goods> goodsList = goodsMapper.selectAllGoods();
return goodsList;
} //带分页返回商品
@Override
public Map<String,Object> getAllGoodsByPage(int currentPage) {
Map<String,Object> res = new HashMap<String,Object>();
PageHelper.startPage(currentPage, 5);
List<Goods> goodsList = goodsMapper.selectAllGoods();
res.put("goodslist",goodsList);
PageInfo<Goods> pageInfo = new PageInfo<>(goodsList);
res.put("pageInfo",pageInfo);
return res;
}
}

4,GoodsMapper.java

@Repository
@Mapper
public interface GoodsMapper {
List<Goods> selectAllGoods();
}

5,GoodsMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mmrepo.demo.mapper.GoodsMapper">
<select id="selectAllGoods" resultType="com.mmpojo.demo.pojo.Goods">
select * from goods order by goodsId desc
</select>
</mapper>

6,Goods.java

public class Goods {
//商品id
Long goodsId;
public Long getGoodsId() {
return this.goodsId;
}
public void setGoodsId(Long goodsId) {
this.goodsId = goodsId;
} //商品名称
private String goodsName;
public String getGoodsName() {
return this.goodsName;
}
public void setGoodsName(String goodsName) {
this.goodsName = goodsName;
} //商品标题
private String subject;
public String getSubject() {
return this.subject;
}
public void setSubject(String subject) {
this.subject = subject;
} //商品价格
private BigDecimal price;
public BigDecimal getPrice() {
return this.price;
}
public void setPrice(BigDecimal price) {
this.price = price;
} //库存
int stock;
public int getStock() {
return this.stock;
}
public void setStock(int stock) {
this.stock = stock;
} public String toString(){
return " Goods:goodsId=" + goodsId +" goodsName=" + goodsName+" subject=" + subject+" price=" + price+" stock=" + stock;
}
}

7,goodslist.html

<!DOCTYPE html>
<html lang="en">
<head >
<title >商品列表</title>
<!--全局通用框架样式 begin-->
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta charset="utf-8" />
<meta name="description" content="" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" />
</head>
<body style="font-size: 12px;">
<div style="width:100%;height:10px;background:#eeeeee;font-size: 16px;" ></div>
<div id="content" style="width:1040px;">
<div style="width:150px;float:left;font-size: 12px;background:#eeeeee;" ></div>
<div style="width:790px;float:left;">
<!--main begin-->
<div th:each="goodsone:${goodslist}"
style="border-bottom-style:solid; border-bottom-width: 1px; width:990px;height:60px;font-size:12px;overflow: hidden;border-bottom-color: #eeeeee;">
<div style="float:left;width:20px;overflow: hidden;" th:text="${goodsone.goodsId}"></div>
<div style="float:left;width:200px;height:60px;overflow: hidden;" th:text="${goodsone.goodsName}"></div>
<!--<div style="float:left;width:300px;overflow: hidden;" th:text="${image_one.image_sn}"></div>-->
<div style="float:left;width:200px;overflow: hidden;" th:text="${goodsone.subject}"></div>
<div style="float:left;width:80px;overflow: hidden;" th:text="${goodsone.price}"></div>
<div style="float:left;width:100px;overflow: hidden;" th:text="${goodsone.stock}"></div>
<div style="float:left;width:160px;overflow: hidden;" ></div>
</div>
<!--page info begin-->
<div align="center">
<a class="allpage"><b th:text="'共 '+ ${pageInfo.getPages()}+ ' 页'"></b></a>
<a th:href="@{/home/goodslist/(p=${pageInfo.getNavigateFirstPage()})}" >首页</a>
<a th:if="${pageInfo.isHasPreviousPage()} == true" th:href="@{/home/goodslist/(p=${pageInfo.getPrePage()})}" >上一页</a> | <span th:each="i,iterStat :${#numbers.sequence(pageInfo.getNavigateFirstPage(), pageInfo.getNavigateLastPage())}" >
<a th:href="@{/home/goodslist/(p=${i})}" th:text=" ${i} "> </a>
<span th:text=" ${iterStat.last}? '':'|' ">|</span> </span>
|
<a th:if="${pageInfo.isHasNextPage()} == true" th:href="@{/home/goodslist/(p=${pageInfo.getNextPage()})}" >下一页</a>
<a th:href="@{/home/goodslist/(p=${pageInfo.getNavigateLastPage()})}" >尾页</a>
</div>
<!--page info end-->
<!--main end-->
</div>
</div> </body>
</html>

五,测试效果

1, 打包:

maven界面,root项目下,先执行clean

然后再执行package

即可以在mmweb项目的target目录下看到jar包

demo-0.01-SNAPSHOT.jar,就是生成的jar包

2,运行jar包

#nohup: 让命令在后台执行,即使终端关闭也不会退出

[root@localhost target]# nohup /usr/local/soft/jdk-12.0.2/bin/java -Xms256m -Xmx256m -jar /data/springboot2f/multimodjar/mmweb/target/demo-0.0.1-SNAPSHOT.jar  >/dev/null 2>&1 &
[1] 30103

如使用此命令,注意把路径替换成自己java命令和jar包的所在路径

3,从浏览器访问:

http://127.0.0.1:8080/home/goodslist/?p=1

返回:

六,查看spring boot的版本:

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

spring boot:多模块项目生成jar包(spring boot 2.3.3)的更多相关文章

  1. android studio 将自己的项目生成jar包

    很多情况下我们开发的项目不是一个完整的app,而是完成一部分功能,供别人的app使用的情况.这时就需要将我们的项目打包生成jar或者arr库文件,让别人的app导入我们的jar包,就能直接使用我们项目 ...

  2. 利用Maven把项目生成jar包供其他项目使用

    每当搭建框架时,第一步就是为系统整理一个接一个的jar包.用多了就开始深思,如何把自己的项目也整成jar包,供他人使用呢? 近期一直在看徐晓斌所著:<Maven实战>.因自己学识不够,只是 ...

  3. Android Studio项目生成Jar包

    步骤: 1)在module的gradle文件中,将apply plugin:'com.android.application'改为apply plugin:'com.android.library' ...

  4. Spring Boot项目生成jar包,并在windows服务器中注册成服务,开机启动

    背景: 使用Spring Boot开发的Web项目,打包生成了一个jar包,希望能部署在Windows服务器中 尝试: 1.Spring Boot生成的jar包,可以直接用java -jar运行,但是 ...

  5. Spring全自动AOP和项目加入jar包

    一.jar可以引进项目中,复制到路下后,要add as library,加载到工作空间中才能引入: 也jar包放在硬盘的项目目录外面,可以多个项目引入共用: 二.xml配置 1.aop全自动配置 2. ...

  6. springboot项目生成jar包(带静态资源)方法

    [Maven]在pom.xml文件中使用resources插件的小作用 不过war包比较实用,毕竟独立的tomcat比较好控制

  7. Spring Boot 多模块项目创建与配置 (一) (转)

    Spring Boot 多模块项目创建与配置 (一) 最近在负责的是一个比较复杂项目,模块很多,代码中的二级模块就有9个,部分二级模块下面还分了多个模块.代码中的多模块是用maven管理的,每个模块都 ...

  8. Spring boot 多模块项目 + Swagger 让你的API可视化

    Spring boot 多模块项目 + Swagger 让你的API可视化 前言 手写 Api 文档的几个痛点: 文档需要更新的时候,需要再次发送一份给前端,也就是文档更新交流不及时. 接口返回结果不 ...

  9. Spring Boot 多模块项目创建与配置 (一)

    最近在负责的是一个比较复杂项目,模块很多,代码中的二级模块就有9个,部分二级模块下面还分了多个模块.代码中的多模块是用maven管理的,每个模块都使用spring boot框架.之前有零零散散学过一些 ...

随机推荐

  1. (超详细)动手编写 — 栈、队列 ( Java实现 )

    目录 前言 栈 概念 栈的设计 编码实现 小结 队列 概念 队列的设计 编码实现 双端队列 概念 设计 编码 循环队列 循环队列 循环双端队列 声明 前言 栈 概念 什么是栈? **栈 **:是一种特 ...

  2. 刀哥多线程自动释放池autoreleasepool

    自动释放池 作用 自动释放对象的 所有 autorelease 的对象,在出了作用域之后,会被自动添加到最近创建的自动释放池中 自动释放池被销毁或者耗尽时,会向池中所有对象发送 release 消息, ...

  3. 面试官问:Mybatis中的TypeHandler你用过吗?

    持续原创输出,点击上方蓝字关注我吧 目录 前言 环境配置 什么是TypeHandler? 如何自定义? 如何将其添加到Mybatis中? XML文件中如何指定TypeHandler? 源码中如何执行T ...

  4. SM4密码算法matlab实现

    %function C=SM4(X,K,M)%M为1时进行加密,M为0时进行解密操作,X为明文/密文输入,K为密钥输入X='0123456789abcdeffedcba9876543210';%X=' ...

  5. use-default-filters的用法

    <context:component-scan base-package="com.atguigu.atcrowdfunding.*" > <context:ex ...

  6. 刷题[极客大挑战 2019]HardSQL

    解题思路 打开是一个登陆框,考点sql注入了,先正常尝试一波 发现居然是get类型 输入and发现有waf过滤,那fuzz一波看看过滤了什么 fuzz union被过滤,并且绕过union的几种方法同 ...

  7. 数据结构 - 堆(Heap)

    数据结构 - 堆(Heap) 1.堆的定义 堆的形式满足完全二叉树的定义: 若 i < ceil(n/2) ,则节点i为分支节点,否则为叶子节点 叶子节点只可能在最大的两层出现,而最大层次上的叶 ...

  8. 对Elasticsearch生命周期的思考

    什么是es索引的生命周期?有啥用?可以怎么用?用了有什么好处呢? 在现实的生产环境中有没有觉得自己刚开始设计的索引的分片数刚刚好,但是随着时间的增长,数据量增大,增长速度增大的情况下,你的es索引的设 ...

  9. Mongodb PHP封装类

    分享一个Mongodb PHP封装类 <?php /** * Mongodb 基本操作API,支持基本类似关系统型数据库的操作接口 * * @version 1.0 * [说明] * * 1:该 ...

  10. mysql-14-transaction

    #TCL /* 事务控制语言 事务:一个或一组sql语句组成一个执行单元,每条sql语句相互依赖 这个执行单元要么全部执行.要么全部失败后回滚 案例:转账 事务的acid属性 1.原子性:事务时一个不 ...