# spring-boot-war
**Repository Path**: jonathanzyf/spring-boot-war
## Basic Information
- **Project Name**: spring-boot-war
- **Description**: No description available
- **Primary Language**: Java
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2020-11-19
- **Last Updated**: 2020-12-19
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# spring-boot-war
本示例是描述如何将Spring Boot项目打包为war并在外部tomcat中运行。主要包含两个调整:
1. 增加WebApplicationInitializer的实现类
2. POM文件调整
## 原则
1. 兼容原有Spring Boot编译、部署、运行形式,对原有的方式**零**影响。
2. 新的方式通过指定Profile形式,便于编译、部署,便于调试。
## 代码与配置调整
### 代码调整
增加WebApplicationInitializer实现类,由启动类实现SpringBootServletInitializer
```java
@SpringBootApplication
public class MyWebApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(MyWebApplication.class, args);
doSomething();
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
// !important 不要忘记了这个,这时不再运行main方法
doSomething();
return builder.sources(new Class[]{MyWebApplication.class});
}
static void doSomething() {
// 额外做一些事情
}
}
```
注意:如果在@SpringBootApplication中配置了scanBasePackage或者scanBasePackageClasses,则不再自动扫描启动类所在的类路径,如果需要,要把自身加上。例如:
```java
@SpringBootApplication(scanBasePackageClasses = {MyWebApplication.class, RabbitMqConfiguration.class})
```
### POM文件调整
1. 通过Profiles配置依赖jar以及打包形式
```xml
jar-mode
jar
true
org.springframework.boot
spring-boot-starter-web
${spring.boot.version}
war-mode
war
false
javax.servlet
javax.servlet-api
4.0.1
provided
org.springframework.boot
spring-boot-starter-web
${spring.boot.version}
org.springframework.boot
spring-boot-starter-tomcat
org.apache.maven.plugins
maven-war-plugin
${maven.war.plugin.version}
false
WEB-INF/lib/*.jar
```
2. 依赖jar提取插件配置
```xml
org.apache.maven.plugins
maven-dependency-plugin
${maven.dependency.plugin.version}
copy-dependencies
prepare-package
copy-dependencies
${project.build.directory}/lib
false
true
false
false
true
runtime
```
## 打包部署
### 编译打包
1. 编译安装依赖的本地类库
```bash
# 编译父工程
mvn clean install -N
# 编译 安装 依赖的本地类库 sample-mq-lib,sample-repo-lib
mvn clean install -pl sample-mq-lib,sample-repo-lib
```
2. 以war模式编译打包sample-spring-war
```bash
# war模式
mvn clean package -DskipTests -Pwar-mode -pl sample-spring-war
# Spring Boot jar模式 , mvn clean package -DskipTests
```
3. 加工war包,将依赖的本地类库打包进来
```bash
# 进入到编译目标文件夹
cd sample-spring-war/target
# 整理依赖的本地类库,从lib中将本地jar移走
mkdir -p locallib/WEB-INF/lib
mv lib/sample-*.jar locallib/WEB-INF/lib/
# 加工war包,将依赖的本地类库打包进来
jar uvf sample-spring-war-1.0-SNAPSHOT.war -C locallib/ .
# 查看war结构是否正确
jar tvf sample-spring-war-1.0-SNAPSHOT.war
```
4. 加工war包,将链接命令打包进来
```bash
# 进入到编译目标文件夹
cd sample-spring-war/target
# 生成链接命令
ls -1 lib| awk '{print "ln ../../common/lib/"$1" WEB-INF/lib/"$1}'>link.sh
# 加工war包,将链接命令打包进来
jar uvf sample-spring-war-1.0-SNAPSHOT.war link.sh
# 查看war结构是否正确
jar tvf sample-spring-war-1.0-SNAPSHOT.war
```
### 在tomcat下部署
1. 拷贝war以及lib到tomcat的webapps下
```bash
# 进入到编译目标文件夹
cd sample-spring-war/target
# 拷贝war到tomcat的webapps下
cp sample-spring-war-1.0-SNAPSHOT.war /usr/local/apache-tomcat-9.0.40/webapps/
# 这是仅是测试,实际上并不是简单将所有依赖的jar都拷贝到common/lib中,是需要经过分析的
# 依赖分析的说明文档地址:https://gitee.com/jonathanzyf/separation-and-merge/blob/master/README.md
cp lib/*.jar /usr/local/apache-tomcat-9.0.40/common/lib/
```
2. 解压war并创建链接
```bash
# 进入tomcat的webapps下
cd /usr/local/apache-tomcat-9.0.40/webapps/
# 解压war
tar xzvf sample-spring-war-1.0-SNAPSHOT.war -C sample-spring-war
# 进入到sample-spring-war
cd sample-spring-war
# 执行链接文件
sh link.sh
# 检查依赖jar是否正确
ls WEB-INF/lib
# 移除war
mv sample-spring-war-1.0-SNAPSHOT.war sample-spring-war-1.0-SNAPSHOT.war.bak
```
### 运行tomcat
```bash
# 进入tomcat目录
cd /usr/local/apache-tomcat-9.0.40
# 启动tomcat
bin/startup.sh
# 查看端口监听状态Linux
ss -tunlp|grep 8080
# 查看端口监听状态Mac
lsof -i:8080
# 测试
curl -v -X GET http://localhost:8080/sample-spring-war/
```
## war本地测试
1. 配置jetty插件,端口配置为9500
```xml
org.eclipse.jetty
jetty-maven-plugin
${jetty.version}
shutdown
9967
automatic
9500
10
/
target/access-yyyy_mm_dd.log
yyyy_MM_dd
yyyy-MM-dd HH:mm:ss
GMT+8:00
true
true
120
true
```
2. 调试信息配置
```bash
# 假设开发工具为Idea,则在`Edit Configurations`中新增Maven配置:
Working directory: 选择模块
Command line: jetty:run
Profiles (separated with space): war-mode
```
3. 测试
```bash
# 然后Debug启动即可运行,测试(jetty插件配置的port为9500)
curl -v -X GET http://localhost:9500/
```