jar包解读
一、什么是jar包
jar包就是 Java Archive File,顾名思义,它的应用是与 Java 息息相关的,是 Java 的一种文档格式,是一种与平台无关的文件格式,可将多个文件合成一个文件。jar 包与 zip 包非常相似——准确地说,它就是 zip 包,所以叫它文件包。jar 与 zip 唯一的区别就是在 jar 文件的内容中,包含了一个 META-INF/MANIFEST.MF 文件,该文件是在生成 jar 文件的时候自动创建的,作为jar里面的"详情单",包含了该Jar包的版本、创建人和类搜索路径Class-Path等信息,当然如果是可执行Jar包,会包含Main-Class属性,表明Main方法入口,尤其是较为重要的Class-Path和Main-Class。
此外,值得注意的是,因为jar包主要是对class文件进行打包,而java编译生成的class文件是平台无关的,这就意味着jar包是跨平台的,所以不必关心涉及具体平台的问题。说到jar里面的文件,咱们来看看最普通的一个带有静态页面的springboot项目jar里面的内容,就会发现解压出来的jar并不简单,为了贴近实际咱们未做任何删减,可以看到有很多东西
只需要运行如下指令,就能看到jar里面的内容(调用jar指令的前提是已经配置了jdk的环境变量)
jar -tf springbootdemo-0.0.1-SNAPSHOT.jar
其中-tf 后接的jar就是我们要查看的jar。
大致看看里面的东西我们可以发现,除了.MF以及.class文件之外,jar还能打包静态资源文件如.html、.css以及.js等项目所需的一切,这也就意味着咱们能将自己的项目打成jar,即不管是web应用还是底层框架,都能打成jar包。
有的jar包是可以直接通过 java -jar 指令来执行的。我们都知道,有的类之所以能够执行,是因为它用你有main函数,该函数是程序的入口,同理,可执行的jar包中肯定是有某个.class文件提供了main函数才使得其可执行。那么问题来了,一个jar里面可能存在多个.class文件都有main函数的情况,我怎么知道该执行哪个?其实答案非常简单,就是看前面说的MANIFEST.MF里面的Main-Class属性,它会指定函数入口。
二、为什么要打jar包
当我们开发了一个程序以后,程序中有很多的类,如果需要提供给别人使用,发给对方一大堆源文件是非常不好的,因此通常需要把这些类以及相关的资源文件打包成一个 jar 包,把这个 jar 包提供给别人使用,同时提供给使用者清晰的文档。这样他人在拿到我们提供的jar之后,就能方便地进行调用。而且安全。能够对JAR文件进行数字签名,只让能够识别数字签名的用户使用里面的东西。
因此,建议大家在平时写代码搬砖的时候,注意把自己代码的通用部分抽离出来,主键积累一些通用的util类,将其逐渐模块化,最后打成jar包供自己在别的项目或者模块中使用,同时不断打磨jar里面的内容,将其做得越来越容易理解和通用,这样的好处是除了会对你的代码重构能力以及模块抽象能力有很好的帮助之外,更是一种从长期解放你的重复工作量,让你有更多的精力去做其他事情的方式,甚至当你抽象出业内足够通用的jar之后,jar包还能为你带来意想不到的利润(当然公司里该保密的东西还是得保密的)。这也是java发展得如此之好的原因,无论出于盈利或者非盈利的目的,将自己的通用工具或者框架抽取出来,打成jar包供他人调用,使得整个java生态圈变得越来越强大–几乎很多业务场景都能找到对应的jar包。
三、如何打jar包
1、通过jdk命令
A:含有多个类的jar,类之间存在调用关系
先创建一个java项目,编写两个非常简单的类,Welcome.java和Teacher.jar,其中Welcome类在main函数里调用了Teacher类的静态方法greeting
Welcome.java
packagecom.imooc.jardemo1;
importcom.imooc.jardemo1.impl.Teacher;
publicclassWelcome{
publicstaticvoidmain(String[] args){
Teacher.greeting();
}
}
Teacher.java
packagecom.imooc.jardemo1.impl;
publicclassTeacher{
publicstaticvoidgreeting(){
System.out.printf("Welcome!");
}
}
在命令行里,去到项目的src路径下,执行javac指令
javac com/imooc/jardemo1/Welcome.java
此时就会生成与这两个类相对应的.class字节码文件
由于jvm实际解析的是.class字节码文件而非.java文件,且jar中最好不要包含代码源文件,我们来将.class文件打个jar包,在src根目录下执行如下指令
jar -cvf welcome.jar com/imooc/jardemo1/Welcome.class com/imooc/jardemo1/impl/Teacher.class
c表示要创建一个新的jar包,v表示创建的过程中在控制台输出创建过程的一些信息,f表示给生成的jar包命名
打jar的时候,会生成一个META-INF的目录,里面有MANIFEST.MF这个清单列表。内容为:
Manifest-Version: 1.0 Created-By: 11 (Oracle Corporation)
此时生成的jar包还不能执行,因为缺少咱们先前说的Main-Class属性,导致jar被执行的时候,不知道执行哪个main函数。因此我们需要加上Main-Class,后接main函数所在类的全路径名(注意冒号之后一定要跟英文的空格,整个文件最后有一行空行)。
Manifest-Version: 1.0 Created-By: 11 (Oracle Corporation) Main-Class:
com.imooc.jardemo1.Welcome
添加完成后,重新执行指令打包,这次咱们在打包指令里多加一个参数,即多传入修改完成后的MANIFEST.MF文件
jar -cvfm welcome.jar META-INF/MANIFEST.MF com/imooc/jardemo1/Welcome.class com/imooc/jardemo1/impl/Teacher.class
其中多了一个参数m,表示要定义MANIFEST文件。之后再重新执行
java -jar welcome.jar
就会发现jar已成功执行