工程部署

在编写完一个SpringBoot应用后,我们可以将其打包成可执行的Jar包并直接部署到生产环境,这种方式比较简单,也是实际开发中最推荐的部署方式。此外,我们还可以将SpringBoot程序打包成War包,并部署到应用服务器(如Tomcat),下面介绍如何进行这一过程。

打包成Jar包

首先我们要确保SpringBoot工程的打包方式为Jar,这个<packaging>属性不指定时其默认值也为Jar,因此我们可以明确指定为Jar或不指定。

<packaging>jar</packaging>

然后我们执行Maven的打包命令。

mvn package

此时我们就可以直接运行得到的Jar包了。

java -jar demo-0.0.1-SNAPSHOT.jar

实际生产环境中,我们通常需要指定很多JVM参数、系统参数等,对于Tomcat部署War包的情况我们都知道可以使用JAVA_OPTS环境变量指定参数,在Jar包部署的情况下,这些信息可以通过JAVA_TOOL_OPTIONS环境变量指定。

打包成War包

如果希望打包为War包,首先需要修改Maven的打包方式。

pom.xml

<packaging>war</packaging>

接着,我们还需要对SpringBoot的内嵌Tomcat进行一些配置。

DemoServletInitializer.java

package com.gacfox.bootdemo;

import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;

public class DemoServletInitializer extends SpringBootServletInitializer {
    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
        //载入配置类
        return builder.sources(DemoApplication.class);
    }
}

这个Java类的作用相当于web.xml,它引入了包含许多配置信息的DemoApplication.class(实际上许多配置信息都是默认配置或是间接引入的)。

然后我们执行Maven的打包命令。

mvn package

这样我们就得到了一个War包。

这个War包有两种使用方式,一种是将War包复制到Tomcat的webapps目录即可,但需要注意修改相关的context配置;另外,SpringBoot的War包依然可以像Jar包一样直接启动,我们执行java -jar demo-0.0.1-SNAPSHOT.war命令即可,这是因为我们得到的War包中仍然包含主函数,打包后的META-INF中也指定了MAIN-CLASS等信息,因此可以直接运行。

前后端分离工程部署

基于Nginx部署

实际开发中,对于一个采用History路由的前后端分离工程,我们通常采用Nginx进行部署,Nginx会将服务端API反向代理到SpringBoot服务上,而对于前端页面的访问则直接由Nginx提供静态文件,这是通用的做法,下面是一个Nginx的配置例子。

location /api/ {
    proxy_pass   http://127.0.0.1:8080;
}

location / {
    root /usr/share/nginx/html;
    index index.html index.htm;
    try_files $uri $uri/ /index.html;
}

上面配置中,/api开头的请求指向后端SpringBoot工程,其它将返回静态文件和主页index.html,具体页面由前端路由决定。

前后端合并打包部署

在某些极特殊情况下,我们需要将前后端工程合并打包(即前端静态资源也由SpringBoot的内置Web服务器提供),实际上这也是可以实现的,一种简单可靠的实现思路就是在SpringBoot服务端手动将前端路由再次指定,让这些路由全部返回前端工程的index.html即入口页面,下面是具体的配置方法。

首先将前端工程编译,并将构建输出结果黏贴到src/main/resources/static文件夹内,其次我们需要保证SpringBoot工程引入了spring-boot-starter-thymeleaf,这是由于为了让SpringBoot工程能够处理HTML页面,我们必须有一个ViewResolver。

pom.xml

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

然后我们配置application.properties,让SpringBoot能正确找到前端工程生成的index.html和其它静态资源。

application.properties

spring.thymeleaf.prefix=classpath:/static/
spring.web.resources.static-locations=classpath:/static/
spring.mvc.static-path-pattern=/**

最后我们还需要添加一个Controller,将所有的前端路由指向index这个视图。

IndexController.java

package com.gacfox.demo.aio.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
public class IndexController {
    @RequestMapping(value = {"/", "/docs"}, method = RequestMethod.GET)
    public String index() {
        return "index";
    }
}

此时我们就可以将SpringBoot工程构建,得到一个前后端工程合并部署的Jar包(或War包)了。

注意:一般来说,我们都应该使用Nginx或类似的支持反向代理的静态服务器部署前后端分离项目,这是一种最佳实践。合并打包有诸多缺点,比如静态文件由Tomcat提供,这会影响应用服务器并发性能和吞吐量,此外前端工程无法单独更新也不利于版本发布和灰度发布。合并打包仅适用于极特殊场景,例如少数全栈开发者的小型项目或个人独立项目,此时合并打包的产物只有一个Jar包,方便部署;此外还适用于交付非专业用户,用户不会用Nginx或是不理解、拒不提供Nginx的情况,不得不为他们进行合并打包。

作者:Gacfox
版权声明:本网站为非盈利性质,文章如非特殊说明均为原创,版权遵循知识共享协议CC BY-NC-ND 4.0进行授权,转载必须署名,禁止用于商业目的或演绎修改后转载。
Copyright © 2017-2024 Gacfox All Rights Reserved.
Build with NextJS | Sitemap