目录
springboot的jar包含了所需的全部依赖、主类,是可执行的jar包。可以打包为jar包,java -jar用内置tomcat运行;也可以打成war包,用外置tomcat运行。
在开发测试阶段,可以打成war包部署到测试服上,更改代码时只需替换对应的文件,无需重新打包、传输好几百兆的包。打成war包部署需要修改很多配置,很麻烦,正式服上的代码改动频率低,基本都是打成jar包部署,更简便。
springboot项目配置
pom.xml
指定打包方式为war
<groupId>com.chy</groupId>
<artifactId>mall</artifactId>
<version>1.0</version>
<name>mall</name>
<description>mall project for Spring Boot</description>
<!-- 默认jar,此处修改为war -->
<packaging>war</packaging>
处理内置的tomcat
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<!--排除内置的tomcat-->
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--暂时给servlet相关技术提供支持-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
同时使用内置、外置的tomcat会发生冲突,需要用 exclusion 排除内置的tomcat。但排除之后没有servlet技术的相关依赖,通不过编译,所以要引入一个 provided 的 spring-boot-starter-tomcat,在编译、打包、测试时提供暂时性的支持。
根据依赖的最短路径优先原则,内置tomcat的依赖会被更外层的 spring-boot-starter-tomcat 依赖覆盖,也就是说此时内置的tomcat排不排除都可以,反正都是无效的。
说明:provided 的 spring-boot-starter-tomcat 也可以换为其它的servlet依赖,比如
<!--servlet的依赖-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<!--依然要是provided-->
<scope>provided</scope>
</dependency>
<!--如果项目还使用了上古技术jsp,则还需要引入jsp的依赖-->
更推荐用 spring-boot-starter-tomcat,包含的依赖更全,不用考虑jsp之类乱七八糟的问题。
指定打成的包名
<build>
<!--指定打成的包名,需要设置为 server.servlet.context-path 的值 -->
<finalName>mall</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
使用外置tomcat部署时,yml中 server.servlet.context-path 指定的根路径无效,应用启动时自动取 pom.xml -> <build> -> <finalName> 指定以包名作为根路径。
引导类
继承SpringBootServletInitializer,重写configure方法
@SpringBootApplication
public class MallApplication extends SpringBootServletInitializer {
public static void main(String[] args){
SpringApplication.run(MallApplication.class, args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(MallApplication.class);
}
}
也可以提出来写成单独的类
public class ServletInitializer extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(MallSCMApplication.class);
}
}
无需加任何注解,可放在任意包下
tomcat配置
修改端口
使用外置tomcat部署时,yml中 server.port 指定的端口无效,启动时自动使用tomcat的端口,需要将tomcat的端口修改为yml中指定的端口
conf/server.xml -> Connector
<!--将默认的8080改为应用要使用的端口-->
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
修改tomcat的默认部署目录(可选)
conf/server.xml -> Host
<!--appBase指定默认的部署目录,默认为webapps,根据需要修改。可使用相对路径、绝对路径,相对路径相对于tomcat根目录-->
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
<!-- SingleSignOn valve, share authentication between web applications
Documentation at: /docs/config/valve.html -->
<!--
<Valve className="org.apache.catalina.authenticator.SingleSignOn" />
-->
<!-- Access log processes all example.
Documentation at: /docs/config/valve.html
Note: The pattern used is equivalent to using pattern="common" -->
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_log" suffix=".txt"
pattern="%h %l %u %t "%r" %s %b" />
</Host>
部署应用
把war包放在appBase指定的目录下即可(默认是webapps)。更改项目代码后需要重启tomcat才会生效。
常见问题
使用外置tomcat部署时,shutdown.sh不能完全停止应用
常见原因是应用存在守护线程、连接池之类的资源尚未关闭,检查代码,关闭未关闭的资源。
如果仍然存在问题,可以kill -9强制杀死,也可以修改 shutdown.sh,在开头加上
#假设应用使用的端口是7000
pids=(`ps aux|grep 7000 | tr -s ' '| cut -d ' ' -f 2`)
for pid in ${pids[*]}
#杀死所有使用该端口的进程
do
kill -9 ${pid}
#屏蔽后面的原有代码,脚本执行完毕
done
内置tomcat使用的时区不对
在引导类的main()中指定时区即可
public static void main(String[] args) {
// TimeZone.setDefault(TimeZone.getTimeZone("Asia/Shanghai"));
// TimeZone.setDefault(TimeZone.getTimeZone("GMT+8"));
SpringApplication.run(MallApplication.class, args);
}