SpringBoot项目多模块打包部署Docker实战

news2024/11/14 13:48:31

前言

我们好多程序员都只关注功能代码的编写,在一些运维工作上则显得略有不足。这篇文章通过介绍最常见的Maven管理的Spring Boot项目多模块打包部署Docker来介绍一下项目部署过程中操作流程和几个需要注意的点。文章假设读者有前面提到的技术点的前置知识,不过没有也没关系,所涉及到的点都比较简单。

Maven管理多模块项目

在项目过大后都会对项目通过多模块的方式进行拆分,下面来说一下拆分多模块的操作步骤。

首先看一下现在的目录结构。注意现在的项目是使用gradle进行构建的,随后我会把它转为使用maven构建。:
在这里插入图片描述
接下来我们使项目变成父子模块的结构。首先我们新建一个module,命名为demo-web。该模块用来存放web相关功能的代码:
在这里插入图片描述
在这里插入图片描述
现在的机构变成了这样:
在这里插入图片描述
接下来以类似的方式进行整理,整理过后的项目结构是下面这样的。来介绍一下各个模块的功能:common用于存放公共的方法,可以是各种工具类的集合。main模块放spring boot的启动类和一些configure,比如我们将common模块中的普通对象声明为bean。service存放了我们的service层代码。web模块中主要是controller。
在这里插入图片描述

pom文件

接下来看各个模块的pom文件是如何配置的,以及它们各自的作用。

这是父模块的pom文件:

<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>3.1.1</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>pom</packaging>
    <name>demo</name>
    <description>demo</description>
    <modules>
        <module>demo-web</module>
        <module>demo-common</module>
        <module>demo-service</module>
        <module>demo-main</module>
    </modules>
    <properties>
        <java.version>17</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>

其中modules标签内的内容是我们的各个子模块。由于这个demo项目是使用Spring Initializr自动生成的,它给出的是parent是Spring Boot Starter,这一块暂时先不要改动。build标签里使用了spring boot的maven插件,这个插件会在我们使用maven打包时打包成一个jar包,一个jar包运行也是spring boot的精髓所在。也就是说,使用spring boot maven plugin打好的jar包,只需要一个命令java -jar yourjar.jar就可以运行了。

我们再梳理一遍各个模块之间的关系:common是各个模块所依赖的工具模块,它里边的实现可以不依赖spring,因此不需要使用上面的打包工具,也不用依赖于父模块来获得父级依赖(主要是spring)。service模块是服务层代码所在的模块,需要依赖父模块以继承spring的依赖。web模块存放的是controller相关的实现,当然也需要依赖父模块,由于需要使用服务层代码,当然也需要依赖service模块。main模块是spring boot启动类所在的模块,前面提到的打成一个jar包实际上就是去jar里寻找这个启动类。再由启动类带动其余的service模块、web模块运行。因此main块还需要依赖serviceweb模块。

除此之外,还需要注意的一个点是,由于我们让serviceweb继承了父模块,因此也会继承了父模块的打包组件spring boot maven plugin,在打包时也会把这两个模块打成spring boot格式的jar包,而这种格式需要有一个主类作为入口(就是我们的spring boot启动类),但是我们这两个都是服务模块并没有啊。因此还需要在打包的时候做一些调整,使用下面的build标签来跳过打可执行jar包的步骤,让这两个模块打出来的是普通的jar包。

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

Docker部署

在部署之前确保你有docker环境,这里就不再赘述了。我们的想法是使用docker file制作一个镜像,然后在镜像中运行我们的自己的多模块项目。前边提到,只需要将main模块打好的jar包使用java -jar命令执行一下就能启动了。因此把这个打好的jar包放到镜像里就可以了。西面是docker file的编写:

# 使用基础的Java镜像
FROM openjdk:latest

# 将构建好的Spring Boot JAR文件复制到容器中
COPY demo-main/target/demo-main-0.0.1-SNAPSHOT.jar /usr/src/myapp/app.jar

# 设置工作目录
WORKDIR /usr/src/myapp

# 暴露 Spring Boot 应用程序的端口
EXPOSE 8080

# 运行 Spring Boot 应用程序
CMD ["java", "-jar", "app.jar"]

写完docker file后运行下面命令来制作镜像:sudo docker build -t demoApp . 不要忘记最后有个.

镜像制作好后使用下面命令来后台启动容器并将端口映射为8080:sudo docker -d demoApp -p 8080:8080。现在就可以在浏览器中访问你部署好的项目了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/736465.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C#(五十八)之C#List

前几天&#xff0c;看同事写的代码中有list相关的字眼&#xff0c;百度了一下&#xff0c;原来是C#中list泛型集合。 了解一下。 List&#xff1a;泛型集合&#xff0c;List<T>类是 ArrayList 类的泛型等效类。该类使用大小可按需动态增加的数组实现 IList<T> 泛型…

Maven工程分模块开发讲解及入门案例

1.分模块开发的意义 一个模块只做自己对应的功能&#xff0c;提升开发效率&#xff0c;将一个工程拆分成若干个子模块方便之间相互调用&#xff0c;接口共享&#xff0c;降低耦合度提高代码复用率。 2.分模块开发入门案例 下面将domain这个模块从当前模块当中给拆分出来。 …

开心档之CSS 测验

目录 CSS 测验 CSS 测验 CSS测验是一种衡量前端开发人员对CSS的熟练程度的测试。通过CSS测验&#xff0c;可以评估一个人对CSS语言的掌握程度和应用能力&#xff0c;帮助公司或招聘方挑选合适的人才。下面将介绍如何进行CSS测验以及一些常见的CSS考题。 一、CSS测验的类型 1…

OpenCV 入门教程:寻找和绘制轮廓

OpenCV 入门教程&#xff1a;寻找和绘制轮廓 导语一、寻找轮廓二、绘制轮廓三、示例应用3.1 目标检测和定位3.2 图像分割 总结 导语 寻找和绘制轮廓是图像处理中常用的技术之一&#xff0c;用于识别、定位和分析图像中的目标区域。在 OpenCV 中&#xff0c;寻找和绘制轮廓可以…

「2024」预备研究生mem-行程问题

一、行程问题 二、课后题 往返 上山下山

LeetCode[75]颜色分类

难度:Medium 题目&#xff1a; 给定一个包含红色、白色和蓝色、共 n 个元素的数组 nums &#xff0c;原地对它们进行排序&#xff0c;使得相同颜色的元素相邻&#xff0c;并按照红色、白色、蓝色顺序排列。 我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。 必须在不使用库…

【前端面试专栏】用户输入网址到页面返回都发生了什么?

&#x1f431; 个人主页&#xff1a;不叫猫先生&#xff0c;公众号&#xff1a;前端舵手 &#x1f64b;‍♂️ 作者简介&#xff1a;2022年度博客之星前端领域TOP 2&#xff0c;前端领域优质作者、阿里云专家博主&#xff0c;专注于前端各领域技术&#xff0c;共同学习共同进步…

软件安全测试流程与方法分享(下)

安全测试是在IT软件产品的生命周期中&#xff0c;特别是产品开发基本完成到发布阶段&#xff0c;对产品进行检验以验证产品符合安全需求定义和产品质量标准的过程。安全是软件产品的一个重要特性&#xff0c;也是CNAS测试认证中非常重要的项目&#xff0c;本系列文章我们与大家…

linux 信号原理 信号处理设置signal, 信号发送kill,信号等待sigsuspend,信号阻塞sigprocmask,一网打尽信号使用

​专栏内容&#xff1a; postgresql内核源码分析 手写数据库toadb 并发编程 个人主页&#xff1a;我的主页 座右铭&#xff1a;天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物. 概述 信号是一种软中断的方式&#xff0c;让进程陷入中断处理调…

vector的resver和resize

#include <iostream> #include <vector> using namespace std; int main() {std::vector<std::vector<std::vector<int> > > a(2);//创建2个vector<vector<int> >类型的数组vector<int> vec;//vec.resize(10); //结果1vec.res…

【Linux之拿捏信号3】阻塞信号

文章目录 相关概念原理sigset_t信号集信号集操作函数sigprocmask系统调用sigpending 相关概念 实际执行信号的处理动作——信号递达Delivery&#xff08;例如自定义捕捉动作&#xff0c;core&#xff0c;Term终止进程的动作&#xff09;。信号从产生到递达之间的状态——信号未…

Verilog基础之十四、FIFO实现

目录 一、FIFO 1.1 定义 1.2 实现方式 1.3 实现原理 二、代码实现 三、仿真结果 3.1 复位阶段 3.2 写入阶段 3.3 读取阶段 3.4 同时读写或不读不写 四、参考资料 一、FIFO 1.1 定义 FIFO(First in First out)为先进先出队列&#xff0c;具有存储功能&#xff0c;…

一篇带你彻底搞懂线程池

目录 一、自定义线程池 1、产生背景 2、堵塞队列 3、线程池 4、拒绝策略 二、ThreadPoolExecuor 1、线程池状态 2、构造方法 3、newFixedThreadPool 4、newCachedThreadPool 5、newSingleThreadExecutor 6、提交任务 7、关闭线程池 三、异步模式之工作线程 1、定…

C-数据的储存(上)

文章目录 前言&#x1f31f;一、数据类型详细介绍&#x1f30f;1.内置类型&#x1f4ab;&#xff08;1&#xff09;.整形家族&#x1f4ab;&#xff08;2&#xff09;.浮点数家族&#x1f30f;2.构造类型&#xff08;也称自定义类型&#xff09;&#x1f30f;3.指针类型&#x…

OpenCV 入门教程:Haar特征分类器

OpenCV 入门教程&#xff1a; Haar 特征分类器 导语一、Haar特征分类器原理二、Haar特征分类器步骤三、示例应用总结 导语 Haar 特征分类器是图像处理中常用的目标检测算法&#xff0c;用于识别图像中的特定目标。该算法基于 Haar-like 特征模板&#xff0c;通过训练分类器来实…

ArcGIS PRO基础教程(一)

操作要求 1.面积为50-80亩 2.不能选在有耕地、园地内 3.坡度小于15度,高程在以下1930 4.距离水源地在300米以内 已知数据 1.等高线图 CONTOUR 2.土地利用图 parcel 3.水系图 water 操作步骤 创建工程,模板选地图就可以了(注:在arcgis pro中创建工程可以看作在arcg…

大火的ChatGPT与表格插件结合会有哪些意想不到的效果?

大火的ChatGPT与表格插件结合会有哪些意想不到的效果&#xff1f; 摘要&#xff1a;本文由葡萄城技术团队于CSDN原创并首发。转载请注明出处&#xff1a;葡萄城官网&#xff0c;葡萄城为开发者提供专业的开发工具、解决方案和服务&#xff0c;赋能开发者。 ChatGPT已经火了好…

前端全集Ⅰ---- HTML/CSS/JavaScript

一 介绍web开发 Web&#xff1a;全球广域网&#xff0c;也称万维网&#xff0c;能够通过浏览器访问的网站 Web网站的工作流程&#xff1a;&#xff08;前后端分离模式&#xff09; 网页有哪些组成&#xff1f; 文字、图片、视频、音频、超链接 前端代码通过浏览器的解析和渲…

3-exercises

解&#xff1a; &#xff08;1&#xff09;Create a tensor a from list(range(9)). Predict and then check the size, offset, and stride. 创建列表a 将其转化为张量 a.size&#xff1a;The size (or shape, in NumPy parlance) is a tuple indicating how many elements a…

脚本引流是什么?其实很好理解,就是利用软件脚本来引流,这种软件我们通常叫引流脚本

脚本引流是什么&#xff1f;其实很好理解&#xff0c;就是利用脚本来引流&#xff0c;这种软件我们通常叫引流脚本&#xff0c;引流脚本的研发就是结合了以往的那些加人软件&#xff0c;从中吸取了长处并且升级了功能&#xff0c;而且通过不断的测试改进&#xff0c;在今年的7月…