SpringBoot系列: 极简Demo程序和Tomcat war包部署

=================================
SpringBoot 标准项目创建步骤
=================================
使用 Spring IDE(Eclipse), 可以新建一个 Spring starter project项目, 是一个项目向导, 在向导提示下可以按需添加 SpringBoot的常用依赖项目, 该向导生成一个非常规范的 pom.xml, 非常规范的目录结构, 值得推荐.

=================================
创建极简SpringBoot tomcatsample程序的步骤
=================================
1. 准备 JDK8
2. Eclipse 中创建 Maven Project, archetype 选择 quickstart那个即可.
groupid 为: com.springbootsample
artifactId 为: tomcatsample
3. 配置 pom.xml 文件, 包括:
a) 增加 spring-boot-starter-parent parent节点
b) 增加 spring-boot-starter-we 依赖项
c) 增加 spring-boot-devtools 依赖项(开发辅助包)
d) 增加 spring-boot-maven-plugin build 插件
4. 手工增加 resources 目录, controller/entity/service等java 目录,
手工添加 application.properties 文件, 设置端口号和url根, 内容如下:
server.port=8888
server.servlet.context-path=/tomcatsample
#server.context-path=/tomcatsample #SpringBoot V1 property, not works in SB2
5. 最终的项目结构如下:

└─src
│ └─main
│ ├─java
│ │ └─com
│ │ └─springbootsample
│ │ └─tomcatsample
│ │ ├─controller <dir>
│ │ ├─entity <dir>
│ │ └─service <dir>
│ │ └─App.java <主程序文件>
│ └─resources
│ └─templates <dir>
│ └─application.properties <配置文件>
├─pom.xml <Maven 主文件>
├─.project <Eclipse 项目文件>
└─.classpath <classpath 文件>
6. App.java 中, 使用 @SpringBootApplication 注解
7. 在 controller 目录下增加一个 IndexController, 用来做 url mapping.

=================================
将 SpringBoot 部署到外置的Tomcat中
=================================
SpringBoot 2需要servlet V3的支持, 所以需要使用Tomcat 7或8, 我使用的是tomcat 8. 
系统开发时一般都是使用SpringBoot 内置tomcat运行的, 很方便. 而在生产环境中, 通常需要将SpringBoot部署在外置Tomcat server上. 网上很多示例都只能运行在内置tomcat中, 这里提供一个兼容内置/外置Tomcat的样例, 代码和配置需要做一些调整.

步骤有:
1. 修改 pom.xml, 这包括:
a) 修改为 war 打包形式
b) 使用 spring-boot-maven-plugin 编译插件, 目标包将是fat war或fat jar, 可以直接运行.
c) 将依赖项 spring-boot-starter-tomcat 标示为 provided.
d) 在 properties tag 下, 增加 start-class tag, 指定SpringBoot程序的真正入口
e) 在 build tag 下, 增加 finalName tag, 缩短war包的文件名, 否则url地址将包含版本信息, 比如url包含: tomcatsample-0.0.1-SNAPSHOT , 非常不友好.
2. 修改主程序入口类
主程序类需要继承SpringBootServletInitializer, 并重写configure()方法.
3. 使用 maven package 打包成 war 包, 并复制到 tomcat安装目录的webapps子目录下.
4. 修改 tomcat 的 confserver.xml 文件, 搜索 8080 并用新端口替换, 比如换成 8888 .
5. 使用 tomcat 的 binstartup.bat启动
6. 访问 web url,
比如: http://127.0.0.1:8888/tomcatsample/index

=================================
其他说明
=================================
1. 这种 war 包是一个 fat 的 executable 压缩包, 包含所有的资源文件和依赖jar包.
2. 使用这种 war 包可以简化了程序部署, 只需部署一个文件即可. 启动Tomcat时, tomcat会自动解压war包到webapps目录, 并启动我们的SpringBoot应用. 将来升级程序, 也仅仅需要覆盖war包即可, tomcat会自动使用新的war包.
3. SpringBoot参数解析器非常智能, 不管参数名是按照驼峰写法, 还是按照下划线写法, 还是按照连接符写法, 都能自动和Bean中的属性关联起来. 即参数中 server.servlet.contextPath 和 server.servlet.context_path 和 server.servlet.context-path 写法其实都是等价的.

=================================
SpringBoot程序的几种启动方式:
=================================
1. [内置tomcat]在Eclipse 以 Java Application 的形式
2. [内置tomcat]使用 mvn spring-boot:run 启动
3. [外置tomcat]使用tomcat的 startup 脚本启动
4. [内置tomcat]使用 java jar tomcatsample.war 的形式.
针对第4种运行方式, 可以传入新参数来覆盖SpringBoot默认值或application.properties的设定值, 比如:
a) 最简启动形式
java -jar tomcatsample.war
b) 以 jvm 环境变量的形式传入 server.port 值
java -Dserver.port=5566 -jar tomcatsample.war
c) 以 application.properties的形式传入 server.port 值
java -jar tomcatsample.war --server.port=7788
java -jar tomcatsample.war server.servlet.context-path
相比 -D 环境变量的形式, 更推荐使用--传参, 因为该传参名称和 application.properties 中的配置项写法完全一致, 而-D的环境变量名称有时候和 application.properties 中的配置项名称不一致.


=================================
tomcatsample 代码
=================================

App.java

package com.springbootsample.tomcatsample;

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


//在内嵌Tomcat开发或部署, 下面写法最简单.
//@SpringBootApplication
//public class App
//{
//    public static void main( String[] args )
//    {
//        SpringApplication.run(App.class, args);
//    }
//}


// 要在外置Tomcat上部署, 需要继承SpringBootServletInitializer, 并重写configure()方法.
// 需要说明的是, 这种写法对内置Tomcat也同样支持.
@SpringBootApplication
public class App extends SpringBootServletInitializer {

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(App.class);
    }

    public static void main(String[] args) throws Exception {
        SpringApplication.run(App.class, args);
    }

}

IndexController.java

package com.springbootsample.tomcatsample.controller;

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

@Controller
@RequestMapping("/")
public class IndexController {
    @RequestMapping("/index")
    @ResponseBody
    public String index() {
        return "index1";
    }
}

pom.xml

 
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.springbootsample</groupId>
    <artifactId>tomcatsample</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <!-- 打包形式修改为 war -->
    <packaging>war</packaging>

    <name>tomcatsample</name>
    <url>http://maven.apache.org</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <!--optional, 如果项目代码包含多个main()函数, 需要告知SpringBoot真正的入口class-->
        <start-class>com.springbootsample.tomcatsample.App</start-class>
    </properties>

    <!-- 增加依赖 parent 项目spring-boot-starter-parent -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.2.RELEASE</version>
    </parent>

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

        <!-- marked the embedded tomcat servlet container as provided -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
         </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    
        <!-- spring-boot-devtools, 在开发过程中支持Auto restart 和 auto reload, 打包为war/jar不会包含该依赖.-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <!-- optional=true,依赖不会传递,该项目依赖devtools;之后依赖myboot项目的项目如果想要使用devtools,需要重新引入 -->
            <optional>true</optional>
        </dependency>
        
        <!--使用freemarker的starter,里面包含spring-boot-starter-web组件-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-freemarker</artifactId>
        </dependency>
        
        <!--mybatis依赖-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
        </dependency>        
        
        <!--druid连接池依赖-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
        </dependency>   
    </dependencies>

    <build>
        <!-- 重命名打包 jar 的文件, 不含版本信息 --> 
        <finalName>tomcatsample</finalName>
        <plugins>
            <!--optional, 加上spring-boot-maven-plugin, 这样jar/war打包是可以 executable 的 -->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            
            <!--optional, mybatis-generator-maven 插件基于数据table 生成 java code -->
            <plugin>
                <groupId>org.mybatis.generator</groupId>
                <artifactId>mybatis-generator-maven-plugin</artifactId>
                <configuration>
                    <verbose>true</verbose>
                    <overwrite>true</overwrite>
                     <!--配置文件的路径-->
                     <configurationFile>${basedir}/src/main/resources/generatorConfig.xml</configurationFile> 
                </configuration>
            </plugin>            
        </plugins>

         <resources>
           <!-- 将 java 目录下的下面文件以资源文件的形式打包到jar输出文件中 -->
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                    <include>**/*.sql</include>
                    <include>**/*.ddl</include>
                    <include>**/*.txt</include>
                    <include>**/*.md</include>
                </includes>
                <filtering>true</filtering>
            </resource>
        </resources>        
    </build>
</project>    

=================================
参考
=================================
https://www.jianshu.com/p/157eb1ab8524
https://www.mkyong.com/spring-boot/spring-boot-deploy-war-file-to-tomcat/
http://www.codesheep.cn/2018/06/05/SpringBoot%E5%BA%94%E7%94%A8%E9%83%A8%E7%BD%B2%E4%BA%8E%E5%A4%96%E7%BD%AETomcat%E5%AE%B9%E5%99%A8/

原文地址:https://www.cnblogs.com/harrychinese/p/springboot_tomcat_deploy.html