原理分析!如何将 springboot 项目打成 war 包放入 tomcat 中运行
1.需要将 pom.xml 文件的 packaging 设置为 war。
2.改成 war 包之后,就可以直接使用 maven 的命令将项目打成一个 war 包了。
3.将这个 war 包直接放入到 tomcat 中运行。
4.启动 startup.bat,你可以发现控制台,并没有打印 springboot 启动的信息。
从上面的 tomcat 启动信息,可以看到 springboot 并没有启动,即 spring 的环境和 springmvc 的环境,并没有初始化。所以是访问不到项目的。
基于这个结果,我们在想,为什么会启动不了 springboot 的环境呢?即在使用 tomcat 启动我们的 war 包的时候,tomcat 并没有执行到我们的主类(启动类)。
那怎样才能让 tomcat 启动的时候,执行到我们的主类呢?
5.在 springboot 的启动类,继承了 SpringBootServletInitializer 类,重写 configure()方法;然后再使用 maven 的 package 命令重写打 war 包,就可以让 tomcat 启动的时候,执行到我们的主类。
这个时候,我们再将打成的 war 放入到 tomcat 中运行,就可以看到已经打印了 springboot 启动的信息了,即已经初始化了 spring 和 springmvc 的环境了。
6.为什么在 springboot 的主类继承了 SpringBootServletInitializer,tomcat 就可以执行到我们的主类呢?
这个问题,就要涉及到 servlet3.0 的新特性了:
通过上图可以知道,servlet3.0 给我们提供了一个非常牛逼的规范,只要我们按照这个规范,我们就能在 tomcat 启动的时候去掉 web.xml,而且还能初始化 spring 环境。
1.定义了一个新的规范,即在资源文件的 META-INF/services 文件夹下面,有一个以 javax.servlet.ServletContainerInitializer 命名的文件,里面定义一个你自己的类的全类名。同时该类实现 javax.servlet.ServletContainerInitializer 接口,并重写 onStartup 方法 2.在上面这个规范下,所有按照这个规范的 servlet 服务器,例如:tomcat,在服务启动的时候,会自己反射执行这个类的 onStartup()方法 3.通过这个新的规范,我们就不需要按照传统的方法,需要在 web.xml 文件中,初始化 spring 等配置和环境,这样做就能实现零配置,springboot 就是按照这个思想实现零配置的。
这就是为什么 springboot 项目在使用 tomcat 启动的时候,就需要实现 SpringBootServletInitializer 这个类,并重写 configure 方法的原因了。
版权声明: 本文为 InfoQ 作者【Summer】的原创文章。
原文链接:【http://xie.infoq.cn/article/ac187146b44a6e373865ddd87】。未经作者许可,禁止转载。
评论