先说遇到问题的情景:

初次尝试使用spring boot框架写了个小web项目,在Intellij IDEA中能正常启动运行。使用maven 运行install,生成war包,发布到本机的tomcat下,出现异常,主要的异常信息是  .......LifeCycleException。经各种搜索,找到答案。


spring boot因为内嵌tomcat容器,所以可以通过打包为jar包的方法将项目发布,但是如何将spring boot项目打包成可发布到tomcat中的war包项目呢?

1. 既然需要打包成war包项目,首先需要在pom.xml文件中修改打包类型,将spring boot默认的<packaging>jar</packaging>修改为<packaging>war</packaging>形式;

2. 其次spring boot的web项目中内嵌tomcat服务器,所以如果我们想要发布war包到tomcat项目,要讲spring boot中内嵌的tomcat包依赖排除,不然产生冲突,打开下面代码中的注释即可。


<          dependency          >         
                    <          groupId          >org.springframework.boot</          groupId          >         
                    <          artifactId          >spring-boot-starter-web</          artifactId          >         
                    <!--         
                    <exclusions>         
                    <exclusion>         
                    <groupId>org.springframework.boot</groupId>         
                    <artifactId>spring-boot-starter-tomcat</artifactId>         
                    </exclusion>         
                    </exclusions>         
                    -->         
          </          dependency          >


有一点想说的是,如果本地开发的时候依然想要使用spring boot内嵌tomcat进行调试,添加如下依赖即可;


<          dependency          >         
                    <          groupId          >org.springframework.boot</          groupId          >         
                    <          artifactId          >spring-boot-starter-tomcat</          artifactId          >         
                    <          scope          >provided</          scope          >         
          </          dependency          >


3. spring boot发布jar包web程序的入口是main函数所在的类,使用@SpringBootApplication注解。但是如果war包发布至tomcat,需要增加 SpringBootServletInitializer 子类,并覆盖它的 configure 方法,或者直接将main函数所在的类继承 SpringBootServletInitializer 子类,并覆盖它的 configure 方法。代码举例如下,


@SpringBootApplication         
          public           class           DemoApplication           extends           SpringBootServletInitializer {         
                    
                    @Override         
                    protected           SpringApplicationBuilder configure(         
                    SpringApplicationBuilder application) {         
                    return           application.sources(DemoApplication.          class          );         
                    }         
                    
                    
                    public           static           void           main(String[] args) {         
                    SpringApplication.run(DemoApplication.          class          , args);         
                    }         
          }


以上就完成了spring boot项目打包war包的所有步骤,可以发布至tomcat7及其以上版本。

最后还有最重要的一点,如果你本机的tomcat版本和  springboot自动集成的8.0版本不一致。也会出问题,解决办法 :

我本地的Tomcat版本是8.0.28, 而服务器上的Tomcat是7.0.69。 我在本地下了个Tomcat7.0.70部署也报同样错误。更加确定问题跟Tomcat版本有关。经过多方查找资料,最后在Stackoverflow上看到一个老外说SpringBoot默认Servlet容器是基于Tomcat8的

在打好的war包中确实发现了Tomcat相关jar包,而且是Tomcat8的,拿Tomcat8的embed包在Tomcat7下面那肯定是不能用啊 

springboot maevn systemPath 打包没打进去_tomcat

要支持低版本Tomcat需要在maven中指定Tomat版本,配置如下:

<properties>
    <tomcat.version>7.0.69</tomcat.version>
</properties>

然后依赖中加上(这个其实不加也行, 官方文档是加上的)

<dependency>
    <groupId>org.apache.tomcat</groupId>
    <artifactId>tomcat-juli</artifactId>
    <version>${tomcat.version}</version>
</dependency>

加上以后试了下,果然是没问题了。看了下war包中的lib目录,确实已经变成Tomcat7的包了 

springboot maevn systemPath 打包没打进去_tomcat_02

但是我还是有点疑惑, 这样配置打成包岂不是换个Tomcat版本就要重新打次包? 既然是由于SpringBoot内部的Servlet容器造成了这个限制, 那我不用行不行? 又查了很多资料, 还真有办法!

<!-- 打war包时加入此项, 告诉spring-boot tomcat相关jar包用外部的,不要打进去 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-tomcat</artifactId>
    <scope>provided</scope>
</dependency>

试了下, 加上这个后, 上面说Tomcat的版本无需指定了, 耶! ^_^