赞
踩
先看看官网对此是如何描述:
意思是,默认情况下,重新打包目标将用重新打包的工件替换原始工件。对于代表应用程序的模块来说,这是一种合理的行为,但如果您的模块被用作另一个模块的依赖项,则需要为重新打包的模块提供分类器。原因是应用程序类打包在BOOT-INF/classes中,因此依赖模块无法加载重新打包的jar类。如果是这样的话,或者如果你喜欢保留原始工件,并用不同的分类器附加重新打包的工件
网描述中 “重新打包目标将用重新打包的工件替换原始工件。对于代表应用程序的模块来说,这是一种合理的行为”,其中,“对于代表应用程序的模块来说” 这句是重点,这句应该是指的可执行的应用程序,也就是我们的可执行的jar,那么我们在需要打包可独立运行的jar应用程序时,用spring-boot-maven-plugin插件来打包就是比较合理的行为了,通过repackage属性也字面意思理解也正好符合其描述为重新打包目标
再看 “但如果您的模块被用作另一个模块的依赖项,则需要为重新打包的模块提供分类器。原因是应用程序类打包在BOOT-INF/classes中,因此依赖模块无法加载重新打包的jar类”,就是说,如果要打包的模块是作为另一个模块的依赖,而不是可独立运行的jar,那么我们不需要用到spring-boot-maven-plugin插件了,按照Maven工程默认的打包方式即可,因为按照spring-boot-maven-plugin方式打包出来的应用程序类是放在其jar包中的BOOT-INF/classes目录中的,也就是如果依赖包按照 spring-boot-maven-plugin方式打的包将不能被主程序加载和识别,目录结构都不对
下面来看看例子:
这是新建的一个项目,里面包含user、mch、common 三个子模块,默认情况下,user模块是没有设置spring-boot-maven-plugin插件的,这里我先给注释掉了,下面运行打包看看效果
执行java -jar user-1.0-SNAPSHOT.jar 命令运行报错,提示找不到主清单属性,可以看到上图中其实就是提示找不到主程序的入口相关信息,打开jar包中的内容是这样的
里面只包含了当前程序的内容,并没有包含相关的依赖jar,再打开META-INF\MANIFEST.MF文件,里面也没有我们想要看到的主程序入口相关信息
接下来再看看把注释放开,通过spring-boot-maven-plugin的方式打包的效果
重新打包后
可以看到有几个变化,多了一个 user-1.0-SNAPSHOT.jar.original 文件,多了一个 BOOT-INF目录,一个org目录,jar包文件大小也比原来大得多,之前的值有3k
user-1.0-SNAPSHOT.jar.original 文件
根据我的分析,应该就是原始打包件,通过spring-boot-maven-plugin重新打包时,以original命名的方式保留了默认的打包件,对比了之前打的包大小一样吻合
BOOT-INF目录
包含了程序运行需要的所有内容,包括主程序的class以及所有依赖的jar
org目录
一堆springframework运行环境相关的启动加载类
jar包变大了
因为所有的依赖jar都打包进去了
接下来打开BOOT-INF目录下的MANIFEST.ME文件
里面的信息比之前的多了不少,有jdk版本信息、spring运行环境的引导类,还有程序入口类
需要注意的是,在通过spring-boot-maven-plugin插件打包时,需要根据父子工程结构来适当的设置,通常来讲我们只针对需要独立运行的jar设置spring-boot-maven-plugin的打包方式,作为只提供依赖的jar不需要设置
有时候我们为了方便,直接在父工程中设置spring-boot-maven-plugin插件打包方式,这样就不需要每个模块都去设置spring-boot-maven-plugin插件,但是这样的设置的话就会存在问题
上图中,user模块为需要独立运行的主程序模块,common公共模块作为依赖模块被user模块依赖,看看运行打包结果
打包运行时报错 Unable to find main class,提示找不到common模块的主类,没错,既然spring-boot-maven-plugin插件打包出来的是可独立运行的jar,那么必然需要为其提供主程序的入口主类,我们知道在父工程的pom.xml文件中设置的功能在子模块中都是可以继承的,因此common模块也继承了spring-boot-maven-plugin插件打包方式,而实际应用中common模块是不需要主程序的入口主类的,所以出现了Unable to find main class的问题
那么给common模块加上入口主类不就行了吗?答案是否定的,可以看下测试效果
给common模块加上了CommonAplication入口主类,并在user模块中引用了common模块的StringUtils工具类,然后运行打包,结果打包失败,出现了如上错误
上面这个错误乍一眼望上去有些懵,明明将common模块依赖进来了,怎么会报程序包不存在,一般来说如果依赖没有引用到应该是编译都通过不了的,但这里能正常编译,只是打包通过不了
分析这个问题的原因在于,我们在父pom.xml中设置了spring-boot-maven-plugin插件,那么其所有的子模块都继承了这种打包方式,打出来的包都是可独立运行的jar,且class以及依赖都是放在BOOT/INF目录下,如果common.jar按照这种目录结构被依赖,则报程序包不存在这样的错误就不奇怪了,因为两者之间的类目录结构都乱了,当然就会有问题了,正常来说common打出来的依赖包应该是下面这样的
所以针对这个问题,最好还是根据需要在各个需要独立运行的模块中设置spring-boot-maven-plugin插件来打包,就不会存在问题了
另外,我们在基于Maven构建Spring Boot项目时,一般都是在顶层父pom.xml中基于springboot父pom.xml来构建我们的项目的
点其父pom进去看看
发现里面已经为我们定义了spring-boot-maven-plugin插件,我们在自己的模块中只需要引用他就行了,就像下面这样
需要注意的是,spring-boot-maven-plugin插件是针对打jar包的亲情况,如果我们需要构建的是war包的话,就不适用了,这也很好理解,spring-boot-maven-plugin插件打的是可独立运行的jar,而war包通常都是部署在如tomcat等服务器上运行的,不需要独立运行
要打war包的话就需要用到maven-war-plugin插件,这个在springboot父pom.xml中也有定义
在我们的模块中只需要指定war就可以了
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。