大家都知道springboot給我們提供jar和war兩種打包方式。雖然他們倆者之間可以很輕松的進(jìn)行轉(zhuǎn)換,但可能很多人也會(huì)像我一樣會(huì)糾結(jié)那在什么情況下使用war亿扁,在什么情況下使用jar熙尉?還請(qǐng)看官老爺們指點(diǎn)。
ps:文章中代碼經(jīng)過(guò)簡(jiǎn)略,因此適用于對(duì)springboot有過(guò)相關(guān)開(kāi)發(fā)或?qū)W習(xí)經(jīng)驗(yàn)的朋友們驶沼。
jar
要打包成jar包我們需要經(jīng)過(guò)下面幾步:
1. pom文件中設(shè)置
<!-- 告訴sprinboot我們希望以什么方式進(jìn)行打包-->
<packaging>jar</packaging>
...
<!-- 在bulid中設(shè)置 這樣可以指定打包名稱,有時(shí)候我們不希望包名中不包含版本號(hào)-->
<finalName>aggregation</finalName>
2. Application.java中設(shè)置
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
3. 打包
clean package
這時(shí)會(huì)在項(xiàng)目根目錄下生成一個(gè)target包争群,我們的jar包就在該文件夾下回怜。
springboot打包成的jar和普通jar包是有一定區(qū)別的。這是一個(gè)可運(yùn)行的jar包换薄。這樣我們可以直接通過(guò)java -jar 來(lái)直接運(yùn)行這個(gè)jar包玉雾。
我們先來(lái)看下springboot打成jar包后的結(jié)構(gòu)和內(nèi)容:
普通jar:
通過(guò)上面兩個(gè)圖的對(duì)比,我們知道這個(gè)JAR包與傳統(tǒng)JAR包的不同之處在于里面有一個(gè)名為lib的目錄轻要,在這個(gè)目錄中包含了這個(gè)簡(jiǎn)單應(yīng)用所依賴的其他JAR包复旬,其中也包含內(nèi)置的嵌 入式Tomcat,正是使用它冲泥,才能發(fā)布服務(wù)和訪問(wèn)Web資源驹碍。除了我們編寫(xiě)的源碼所編譯形成的CLASS以外,在org目錄下還有許多Spring所提 供的CLASS凡恍,正是依賴這些CLASS志秃,才能夠加載位于lib目錄下JAR中的類(lèi)。這樣的加載機(jī)制與在OSGi bundle中聲明Bundle-Classpath很類(lèi)似嚼酝,不過(guò)在OSGi中會(huì)由容器來(lái)負(fù)責(zé)加載指定路徑下的類(lèi)洽损。這大致闡述了這樣一個(gè)JAR包能夠發(fā)布服務(wù)的原因。
war
要打包成war包我們需要經(jīng)過(guò)以下幾步:
1. pom文件中設(shè)置
<!-- 告訴sprinboot我們希望以什么方式進(jìn)行打包-->
<packaging>war</packaging>
...
<!-- 移除內(nèi)嵌的tomcat模塊革半,但是為了我們?cè)诒緳C(jī)測(cè)試方便碑定,我們還需要引入它,所以配置如下-->
<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>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<!-- 當(dāng)然我們也可以使用Undertow -->
...
<!-- 我們始終是運(yùn)行在severlet容器中的又官,我們知道tomcat中已經(jīng)有了servlet的依賴延刘,但是上面已經(jīng)在打包的時(shí)候移出了那么我們需要設(shè)置-->
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-servlet-api</artifactId>
<version>7.0.42</version>
<scope>provided</scope>
</dependency>
...
<!-- 添加war插件,用來(lái)自定義打包以后的war包的名稱-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<warSourceExcludes>src/main/resources/**</warSourceExcludes>
<warName>springBoot</warName>
</configuration>
</plugin>
上面說(shuō)到的Undertow六敬,大家有興趣可以去研究下碘赖,我這里附上一個(gè)springboot大神的文章Spring Boot 容器選擇 Undertow 而不是 Tomcat
2. Application.java中設(shè)置
修改入口方法 繼承一個(gè)SpringBootServletInitializer類(lèi),并且覆蓋configure方法
@SpringBootApplication
@EnableCaching
public class SpringDataJpaExampleApplication extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(SpringDataJpaExampleApplication.class);
}
public static void main(String[] args) {
SpringApplication.run(SpringDataJpaExampleApplication.class, args);
}
}
3. 打包
clean package
說(shuō)完打包我們來(lái)說(shuō)下一個(gè)話題:
運(yùn)行
- 如果我們是jar包外构,我們可以直接通過(guò)java -jar 來(lái)運(yùn)行 普泡。這種方式如果是在系統(tǒng)中關(guān)閉了控制臺(tái)也就停止該Java進(jìn)程。
在linux的生產(chǎn)系統(tǒng)中我們不希望是上面的結(jié)果审编,我們可以通過(guò)下面的方式運(yùn)行:
nohup java -jar springboot.jar --server.port=port &
另外我還有一篇使用dokcer的文章撼班,也說(shuō)到了怎么來(lái)運(yùn)行和啟動(dòng)它
springboot學(xué)習(xí)記錄之集成docker并發(fā)布到阿里云服務(wù)
- 如果是war包,我們可以將其放到我們常用的web容器tomcat的webapps目錄下垒酬,然后啟動(dòng)tomcat
通過(guò)tomcat我們可以很方便的設(shè)置jvm砰嘁、運(yùn)行線程等等件炉。還可以將多個(gè)應(yīng)用映射到同一個(gè)端口上。
選擇
好了說(shuō)了那么多矮湘,我們首先知道斟冕,哪怕是jar它也是像war一樣,運(yùn)行在容器中來(lái)發(fā)布服務(wù)的缅阳。
再來(lái)說(shuō)下今天的終極目的:jar和war的取舍磕蛇。
到底是jar好?還是war好十办?
我目前認(rèn)為jar包在集群或者做一些優(yōu)化的話秀撇,沒(méi)有war包方便。
而如果很簡(jiǎn)單的應(yīng)用的話jar包卻不會(huì)像war包一樣一定要找web容器運(yùn)行那樣復(fù)雜橘洞。
還望賜教捌袜!