fatjar
看下springboot打成jar包后的結構和內容:
springboot項目打包的jar
普通jar:
傳統jar 通過上面兩個圖的對比,我們知道這個JAR包與傳統JAR包的不同之處在於里面有一個名為lib的目錄,在這個目錄中包含了這個簡單應用所依賴的其他JAR包,其中也包含內置的嵌入式Tomcat,正是使用它,才能發布服務和訪問Web資源。除了我們編寫的源碼所編譯形成的CLASS以外,在org目錄下還有許多Spring所提供的CLASS,正是依賴這些CLASS,才能夠加載位於lib目錄下JAR中的類。這樣的加載機制與在OSGi bundle中聲明Bundle-Classpath很類似,不過在OSGi中會由容器來負責加載指定路徑下的類。這大致闡述了這樣一個JAR包能夠發布服務的原因。
一、packaging的方式不同
一種設置成jar一種是war。 工程采用的是jar 的打包方式,所以在執行package 命令后,會產生一個jar 包。進入到這個目錄用壓縮軟件打開此jar 包,其中我們發現了一個叫lib 的文件夾,打開lib 文件夾發現此文件夾下全是工程依賴的jar 包,甚至還有tomcat。這種包含有jar 包的jar包,我們稱之為fatJAR( 胖jar 包)。 由於fatJAR 本身就包括tomcat , 我們就不需要另外部署了,直接在命令行就可以把我們的應用啟動起來,在命令行,進入到jar 包所在的目錄,我們可以通過以下java –jar命令來執行此jar 包。在控制台會出現啟動信息,在瀏覽器訪問程序
spring-boot 默認提供內嵌的tomcat,所以打包直接生成jar 包,用java -jar 命令就可以啟動。但是,有時候我們更希望一個tomcat來管理多個項目,這種情況下就需要項目是war格式的包而不是jar 格式的包。
(1)修改pom.xml 將打包方式修改為war
<packaging>war</packaging>
添加依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
spring-boot-starter-tomcat 是原來被傳遞過來的依賴,默認會打到包里,所以我們再次引入此依賴,並指定依賴范圍為provided,這樣tomcat 相關的jar就不會打包到war 里了.
(2)添加ServletInitializer
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.web.SpringBootServletInitializer;
public class ServletInitializer extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilderapplication) {
return application.sources(Application.class);
}
}
由於我們采用web3.0 規范,是沒有web.xml 的,而此類的作用與web.xml相同。
(3)運行package 打包命令生成war 包 生成后將war 包放入tomcat,啟動tomcat,測試完成的功能是否可以使用。
二、繼承的方式不同
Application.java需要繼承SpringBootServletInitializer,而jar包不需要。
@SpringBootApplication
@RestController
public class Application extends SpringBootServletInitializer{
public static void main(String[] args) {
SpringApplication.run(Application.class,args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(Application.class);
}
}
三、spring boot內置tomcat
springboot內置tomcat容器,默認tomcat8的版本,war包部署時,需要在pom文件中有關跟tomcat有關系的jar包scope都設置成provided。 或者去掉spring boot內置的tomcat代碼:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<artifactId>log4j-over-slf4j</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
<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>
jar和war的取舍。
到底是jar好?還是war好?
目前認為jar包在集群或者做一些優化的話,沒有war包方便。
而如果很簡單的應用的話jar包卻不會像war包一樣一定要找web容器運行那樣復雜。