默认情况下,SpringBoot 内置 Tomcat,可以直接在 Java IDE 中启动,也可以打成 jar 包,用 java -jar
命令启动。但是,如果要用外部 Tomcat 管理多个项目,就要打成 war 包。本文以 Maven 项目为例,总结了 SpringBoot 各种部署方法和相关事项。为便于演示,我使用的环境是 Windows,而 Linux 下方法大同小异。
作者:王克锋
出处:https://kefeng.wang/2017/12/18/spring-boot-deploy/
版权:自由转载-非商用-非衍生-保持署名,转载请标明作者和出处。
SpringBoot 项目创建方法参考文章 Spring Boot 开发概要
<packaging>jarpackaging>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
dependencies>
spring.main.banner-mode=off
logging.level.org.springframework=INFO
logging.pattern.console=%d{HH:mm:ss.SSS} %p [%F:%L] - %m%n
server.port=8080
@RestController
public class HelloController {
@RequestMapping("/hello")
public String hello() {
return "hello! " + System.currentTimeMillis();
}
}
@SpringBootApplication
public class HelloApplication {
public static void main(String[] args) {
SpringApplication.run(HelloApplication.class, args);
}
}
默认为自带 Tomcat 容器(spring-boot-starter-web 中依赖了 spring-boot-starter-tomcat);
默认打包为 jar 格式,可以像普通应用程序一样启动。
IntelliJ IDEA 中,打开应用类文件(HelloApplication.java)直接运行其中的 main() 即可;
浏览器访问: http://localhost:8080/hello
call mvn.cmd -Dmaven.test.skip=true package
java -jar target\spring-boot-0.0.1-SNAPSHOT.jar
浏览器访问: http://localhost:8080/hello
参考文章 Tomcat 安装及其单机多实例部署
官方资料: Installing Spring Boot applications
借助于服务管理器 systemd,可以部署为单实例或多实例。
之后可以优雅地启动和停止服务,避免暴力 kill。
官方参考资料:
Spring Boot Reference Guide
Traditional deployment
打包方式由 jar 调整为 war;
注意:默认依赖的 spring-boot-starter-tomcat 无需排除,生成的 war 包不但可以部署到外部 Tomcat,还可以像之前一样使用 java -jar
启动。
<packaging>warpackaging>
应用类继承 SpringBootServletInitializer 并重写 configure() 方法。
@SpringBootApplication
public class HelloApplication extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(HelloApplication.class);
}
public static void main(String[] args) {
SpringApplication.run(HelloApplication.class, args);
}
}
修改为自动解压(unpackWARs=”true”),自动部署(autoDeploy=”true”)。
<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true">
Host>
改用侯捷老师的名言,脚本面前无秘密。脚本简单解释如下:
打为 war 包,删除 Tomcat 目录下的项目原目录,复制 war 包,启动 Tomcat。
call mvn.cmd -Dmaven.test.skip=true package
rd /s/q "%CATALINA_HOME%\webapps\spring-boot"
copy /y "target\spring-boot-0.0.1-SNAPSHOT.war" "%CATALINA_HOME%\webapps\spring-boot.war"
call "%CATALINA_HOME%\bin\startup.bat"
浏览器访问: http://localhost:8080/spring-boot/hello
注意 URL 多了个项目名(spring-boot),原因是 Tomcat 需要管理多个项目,解压出的项目多了一层目录名。
只需把 pom.xml 中的 spring-boot-starter-tomcat 排除掉,并增加 spring-boot-starter-jetty。
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-tomcatartifactId>
exclusion>
exclusions>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-jettyartifactId>
dependency>
<dependencies>
可用来区分开发环境、测试环境、生产环境等。
当当前激活的 profile 与 xxx 一致时,相应的 bean 才会实例化。
@Service
@Profile("dev")
class MyServiceDev implements MyService {
}
@Service
@Profile("test")
class MyServiceTest implements MyService {
}
@Service
@Profile("prod")
class MyServiceProd implements MyService {
}
application.properties
中指定 spring.profiles.active=xxx
java -jar spring-boot.jar --spring.profiles.active=xxx
参考文档:Developer tools
所谓热部署,是指每次修改代码后,无需手动重启,修改即可生效。其原理为:
(1) Java 文件修改后,IDEA 自动编译为新的 class 文件;
(2) DevTools 监视到 class 文件有更新,就新建 ClassLoader 加载新的 class,然后把 ClassLoader 由旧切换至新。
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-devtoolsartifactId>
<optional>trueoptional>
dependency>
修改文件 application.properties:
## 如果使用了 Thymeleaf 模板
## 缓存机制,在开发调试阶段禁用(false),上线后要启用(true)
spring.thymeleaf.cache=false
## 为避免服务反复频繁重启,禁用
## 效果:静态资源文件会实时更新,但 class 文件需要手工重启服务
spring.devtools.restart.enabled=false
注意:DEBUG/RUN 状态下不会自动构建,空闲时才自动构建。
注意:无论是否 DEBUG/RUN 状态,都会触发自动构建。