大家都知道springboot給我們提供jar和war兩種打包方式。雖然他們倆者之間可以很輕松的進行轉換,但可能很多人也會像我一樣會糾結那在什么情況下使用war,在什么情況下使用jar?還請看官老爺們指點。
ps:文章中代碼經過簡略,因此適用于對springboot有過相關開發或學習經驗的朋友們。
jar
要打包成jar包我們需要經過下面幾步:
1. pom文件中設置
<!-- 告訴sprinboot我們希望以什么方式進行打包-->
<packaging>jar</packaging>
...
<!-- 在bulid中設置 這樣可以指定打包名稱,有時候我們不希望包名中不包含版本號-->
<finalName>aggregation</finalName>
2. Application.java中設置
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
3. 打包
clean package
這時會在項目根目錄下生成一個target包,我們的jar包就在該文件夾下。
springboot打包成的jar和普通jar包是有一定區別的。這是一個可運行的jar包。這樣我們可以直接通過java -jar 來直接運行這個jar包。
我們先來看下springboot打成jar包后的結構和內容:
普通jar:
通過上面兩個圖的對比,我們知道這個JAR包與傳統JAR包的不同之處在于里面有一個名為lib的目錄,在這個目錄中包含了這個簡單應用所依賴的其他JAR包,其中也包含內置的嵌 入式Tomcat,正是使用它,才能發布服務和訪問Web資源。除了我們編寫的源碼所編譯形成的CLASS以外,在org目錄下還有許多Spring所提 供的CLASS,正是依賴這些CLASS,才能夠加載位于lib目錄下JAR中的類。這樣的加載機制與在OSGi bundle中聲明Bundle-Classpath很類似,不過在OSGi中會由容器來負責加載指定路徑下的類。這大致闡述了這樣一個JAR包能夠發布服務的原因。
war
要打包成war包我們需要經過以下幾步:
1. pom文件中設置
<!-- 告訴sprinboot我們希望以什么方式進行打包-->
<packaging>war</packaging>
...
<!-- 移除內嵌的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>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<!-- 當然我們也可以使用Undertow -->
...
<!-- 我們始終是運行在severlet容器中的,我們知道tomcat中已經有了servlet的依賴,但是上面已經在打包的時候移出了那么我們需要設置-->
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-servlet-api</artifactId>
<version>7.0.42</version>
<scope>provided</scope>
</dependency>
...
<!-- 添加war插件,用來自定義打包以后的war包的名稱-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<warSourceExcludes>src/main/resources/**</warSourceExcludes>
<warName>springBoot</warName>
</configuration>
</plugin>
上面說到的Undertow,大家有興趣可以去研究下,我這里附上一個springboot大神的文章Spring Boot 容器選擇 Undertow 而不是 Tomcat
2. Application.java中設置
修改入口方法 繼承一個SpringBootServletInitializer類,并且覆蓋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
說完打包我們來說下一個話題:
運行
- 如果我們是jar包,我們可以直接通過java -jar 來運行 。這種方式如果是在系統中關閉了控制臺也就停止該Java進程。
在linux的生產系統中我們不希望是上面的結果,我們可以通過下面的方式運行:
nohup java -jar springboot.jar --server.port=port &
另外我還有一篇使用dokcer的文章,也說到了怎么來運行和啟動它
springboot學習記錄之集成docker并發布到阿里云服務
- 如果是war包,我們可以將其放到我們常用的web容器tomcat的webapps目錄下,然后啟動tomcat
通過tomcat我們可以很方便的設置jvm、運行線程等等。還可以將多個應用映射到同一個端口上。
選擇
好了說了那么多,我們首先知道,哪怕是jar它也是像war一樣,運行在容器中來發布服務的。
再來說下今天的終極目的:jar和war的取舍。
到底是jar好?還是war好?
我目前認為jar包在集群或者做一些優化的話,沒有war包方便。
而如果很簡單的應用的話jar包卻不會像war包一樣一定要找web容器運行那樣復雜。
還望賜教!