04运维实用篇(D1_打包运行)
如果不使用Druid数据源,程序运行后是什么样子呢?是独立的数据库连接对象还是有其他的连接池技术支持呢?虽然没有DruidDataSource相关的信息了,但是我们发现日志中有HikariDataSource这个信息,就算不懂这是个什么技术,看名字也能看出来,以DataSource结尾的名称,这一定是一个数据源技术。我们没有手工添加这个技术,那这个技术哪里来的呢?这就是springboot内嵌数据
目录
一、SpringBoot程序的打包与运行
前言
我们天天写程序都是在Idea下写的,运行也是在Idea下运行的。

但是实际开发完成后,我们的项目是不可能运行在自己的电脑上的。

我们以后制作的程序是运行在专用的服务器上的,简单说就是将你做的程序放在一台独立运行的电
脑上,这台电脑要比你开发使用的计算机更专业,并且安全等级各个方面要远超过你现在的电脑。

那我们的程序如何放置在这台专用的电脑上呢,这就要将我们的程序先组织成一个文件,然后将这
个文件传输到这台服务器上。
这里面就存在两个过程,一个是打包的过程,另一个是运行的过程。
扩展:
企业项目上线为了保障环境适配性会采用下面流程发布项目,这里不讨论此过程。
- 开发部门使用Git、SVN等版本控制工具上传工程到版本服务器
- 服务器使用版本控制工具下载工程
- 服务器上使用 Maven 工具在当前真机环境下重新构建项目
- 启动服务
继续说我们的打包和运行过程。
所谓打包指将程序转换成一个可执行的文件,所谓运行指不依赖开发环境执行打包产生的文件。
上述两个操作都有对应的命令可以快速执行。
1. 程序打包
SpringBoot程序是基于Maven创建的,在Maven中提供有打包的指令,叫做package。
本操作可以在Idea环境下执行。
mvn package
打包后会产生一个与工程名类似的jar文件,其名称是由模块名+版本号+.jar组成的。
2. 程序运行
程序包打好以后,就可以直接执行了。
在程序包所在路径下,执行指令。
java -jar 工程包名.jar
执行程序打包指令后,程序正常运行,与在Idea下执行程序没有区别。
- 如果你的计算机中没有安装java的jdk环境,是无法正确执行上述操作的,因为程序执行使用的是java指令。
- 在使用向导创建SpringBoot工程时,pom.xml文件中会有如下配置,这一段配置千万不能删除,否则打包后无法正常执行程序。
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
3. 知识小结
- SpringBoot工程可以基于java环境下独立运行jar文件启动服务
- SpringBoot工程执行mvn命令package进行打包
- 执行jar命令:java –jar 工程名.jar
二、SpringBoot程序打包失败处理
1. 例子
有些小伙伴打包以后执行会出现一些问题,导致程序无法正常执行,例如下面的现象

要想搞清楚这个问题就要说说.jar文件的工作机制了,知道了这个东西就知道如何避免此类问题的
发生了。
搞java开发平时会接触很多jar包,比如mysql的驱动jar包,而上面我们打包程序后得到的也是一个
jar文件。
这个时候如果你使用上面的java -jar指令去执行mysql的驱动jar包就会出现上述不可执行的现象,
而我们的SpringBoot 项目为什么能执行呢?其实是因为打包方式不一样。
在 SpringBoot 工程的 pom.xml 中有下面这组配置,这组配置决定了打包出来的程序包是否可以执
行。
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
我们分别开启这段配置和注释掉这段配置分别执行两次打包,然后观察两次打包后的程序包的差
别,共有3处比较明显的特征
- 打包后文件的大小不同
- 打包后所包含的内容不同
- 打包程序中个别文件内容不同
先看第一个现象,文件大小不同。
带有配置时打包生成的程序包大小如下:
![]()
不难看出,带有配置的程序包体积比不带配置的大了30倍,那这里面都有什么呢?能差这么多?下面看看里面的
内容有什么区别。


我们发现内容也完全不一样,仅有一个目录是一样的,叫做META-INF。
打开容量大的程序包中的BOOT-INF目录下的classes目录,我们发现其中的内容居然和容量小的程序包中的内容
完全一样。


原来大的程序包中除了包含小的程序包中的内容,还有别的东西。都有什么呢?
回到BOOT-INF目录下,打开lib目录,里面显示了很多个jar文件。

仔细翻阅不难发现,这些jar文件都是我们制作这个工程时导入的坐标对应的文件。
大概可以想明白了,SpringBoot程序为了让自己打包生成的程序可以独立运行,不仅将项目中自己开发的内容进
行了打包,
还把当前工程运行需要使用的jar包全部打包进来了。为什么这样做呢?
就是为了可以独立运行。不依赖程序包外部的任何资源可以独立运行当前程序。
这也是为什么大的程序包容量是小的程序包容量的30倍的主要原因。
再看看大程序包还有什么不同之处,在最外层目录包含一个org目录,进入此目录,目录名是
org\springframework\boot\loader,
在里面可以找到一个JarLauncher.class的文件,先记得这个文件。
再看这套目录名,明显是一个Spring的目录名,为什么要把Spring框架的东西打包到这个程序包中呢?不清楚。
回到两个程序包的最外层目录,查看名称相同的文件夹META-INF下都有一个叫做MANIFEST.MF的文件,
但是大小不同,打开文件,比较内容区别
- 小容量文件的MANIFEST.MF
Manifest-Version: 1.0
Implementation-Title: springboot_08_ssmp
Implementation-Version: 0.0.1-SNAPSHOT
Build-Jdk-Spec: 1.8
Created-By: Maven Jar Plugin 3.2.0
- 大容量文件的MANIFEST.MF
Manifest-Version: 1.0
Spring-Boot-Classpath-Index: BOOT-INF/classpath.idx
Implementation-Title: springboot_08_ssmp
Implementation-Version: 0.0.1-SNAPSHOT
Spring-Boot-Layers-Index: BOOT-INF/layers.idx
Start-Class: com.itheima.SSMPApplication
Spring-Boot-Classes: BOOT-INF/classes/
Spring-Boot-Lib: BOOT-INF/lib/
Build-Jdk-Spec: 1.8
Spring-Boot-Version: 2.5.4
Created-By: Maven Jar Plugin 3.2.0
Main-Class: org.springframework.boot.loader.JarLauncher
大文件中明显比小文件中多了几行信息,
其中最后一行信息是Main-Class: org.springframework.boot.loader.JarLauncher。
这句话什么意思呢?
如果使用java -jar执行此程序包,将执行Main-Class属性配置的类,这个类恰巧就是前面看到的那个文件。
原来SpringBoot打包程序中出现Spring框架的东西是为这里服务的。
而这个org.springframework.boot.loader.JarLauncher类内部要查找Start-Class属性中配置的类,并执行对应的类。
这个属性在当前配置中也存在,对应的就是我们的引导类类名。
现在这组设定的作用就搞清楚了
- SpringBoot程序添加配置后会打出一个特殊的包,包含Spring框架部分功能,原始工程内容,原始工程依赖的jar包
- 首先读取MANIFEST.MF文件中的Main-Class属性,用来标记执行java -jar命令后运行的类
- JarLauncher类执行时会找到Start-Class属性,也就是启动类类名
- 运行启动类时会运行当前工程的内容
- 运行当前工程时会使用依赖的jar包,从lib目录中查找
看来SpringBoot打出来了包为了能够独立运行,简直是煞费苦心,将所有需要使用的资源全部都添加到了这个包
里。这就是为什么这个jar包能独立运行的原因。
再来看之前的报错信息:

由于打包时没有使用那段配置,结果打包后形成了一个普通的jar包,
在MANIFEST.MF文件中也就没有了Main-Class对应的属性了,
所以运行时提示找不到主清单属性,这就是报错的原因。
上述内容搞清楚对我们编程意义并不大,但是对各位小伙伴理清楚SpringBoot工程独立运行的机制是有帮助的。
其实整体过程主要是带着大家分析,如果以后遇到了类似的问题,多给自己提问,多问一个为什么,兴趣自己就
可以独立解决问题了。
2. 知识小结
spring-boot-maven-plugin插件用于将当前程序打包成一个可以独立运行的程序包
3. 参考文献
三、命令行启动常见问题及解决方案
在DOS环境下启动SpringBoot工程时,可能会遇到端口占用的问题。
# 查询端口
netstat -ano
# 查询指定端口
netstat -ano |findstr "端口号"
# 根据进程PID查询进程名称
tasklist |findstr "进程PID号"
# 根据PID杀死任务
taskkill /F /PID "进程PID号"
# 根据进程名称杀死任务
taskkill -f -t -im "进程名称"
关于打包与运行程序其实还有一系列的配置和参数,下面的内容中遇到再说,这里先开个头,知道如何打包和运
行程序。
四、SpringBoot项目快速启动(Linux版)
1. 问题
其实对于Linux系统下的程序运行与Windows系统下的程序运行差别不大,命令还是那组命令,
只不过各位小伙伴可能对Linux指令不太熟悉,结果就会导致各种各样的问题发生。
比如防火墙如何关闭,IP地址如何查询,JDK如何安装等等。
2. Linux下快速启动 SpringBoot 工程
2.1. 查看JDK版本
请确保SpringBoot工程使用的java版本与Linux中安装的版本一致
java -version

2.2. 导入SpringBoot工程jar包
- 使用maven命令打包工程

- 打开工程jar目录

- jar包导入到linux
cd / #进入根目录
cd usr #进入usr目录
mkdir BootApp #创建BootApp目录
之后就是将工程jar包导入到我们创建的BootApp目录下:

3. 启动Boot工程
- 前台启动Boot工程
java -jar springboot-SSMP-0.0.1-SNAPSHOT.jar

- 后台启动Boot工程
java -jar springboot-SSMP-0.0.1-SNAPSHOT.jar
> server.log:将日志输入到此文件中2>&1:将标准错误输出重定向到标准输出
nohup java -jar springboot-SSMP-0.0.1-SNAPSHOT.jar > server.log 2>&1 &
命令运行得到的是程序的pid

- 关闭后台启动的Boot工程
ps -ef | grep "java -jar" #查找工程启动命令的pid
kill -9 67691 #消除Boot工程的进程

4. 知识小结
- Boot程序打包依赖SpringBoot对应的Maven插件即可打包出可执行的jar包
- 运行jar包使用jar命令进行
- 只需保证运行环境有效,就可以顺利执行Boot工程
更多推荐




所有评论(0)