SpringBoot项目打jar包供别的项目调用问题

  • Post author:
  • Post category:其他


假如有两个项目A和B,假如A项目想打成jar包,然后在B中引入该jar包。

1、SpringBoot的Maven插件打包

如果用Idea创建的SpringBoot会自带maven打包插件。

<build>

<plugins>

<plugin>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-maven-plugin</artifactId>

</plugin>

</plugins>

</build>

表1.1、引入SpringBoot会自带maven打包插件

然后点击idea左边的Maven Project->你的项目名->Lifecycle->instal就会把这个项目放入你本地的Maven库,如图1.1。而且还会在你的项目下生成一个jar包,如图1.2。

图1.1、打包过程

图1.2、生成的jar包

SpringBoot会自带打包插件打的包不能用。将SpringBoot会自带打包插件打的包解压后会看到它的目录结构,它把包都达到BOOT-INF这个目录下了,引用的时候我们引用不到,会报“Cannot resolve symbol”的错,如图1.3。

图1.3、报的错

2、原生的Maven插件打包

SpringBoot会自带打包插件打的包不能用,不能用我改为用原生的Maven打包插件打包。

<build>

<plugins>

<plugin>

<groupId>org.apache.maven.plugins</groupId>

<artifactId>maven-compiler-plugin</artifactId>

<configuration>

<source>${java.version}</source> <!–指明源码用的Jdk版本–>

<target>${java.version}</target> <!–指明打包后的Jdk版本–>

</configuration>

</plugin>

</plugins>

</build>

表2.1、引入原生maven打包插件

然后点击idea左边的Maven Project->你的项目名->Lifecycle->instal就会把这个项目放入你本地的Maven库,而且还会在你的项目下生成一个jar包,如图2.1。

图2.1、打包过程

图2.2、生成的jar包

这种方式打完包并安到本地仓库后可以通过两种方式引用该jar包。

1、通过你打包项目的坐标然后在调用的项目中引用能够引用的到。

A项目的坐标

<groupId>com.bonc</groupId>

<artifactId>mcp-activiti-invoke</artifactId>

<version>0.0.1-SNAPSHOT</version>

表2.2、打包项目坐标

B项目中引用

<dependency>

<groupId>com.bonc</groupId>

<artifactId>mcp-activiti-invoke</artifactId>

<version>0.0.1-SNAPSHOT</version>

</dependency>

表2.3、引入打包到本地库中jar的坐标

2、我们直接把jar包放在本地,然后通过maven引入本地jar包能够引用到。但是这种方式有个问题,那就是打包那个项目的依赖不会打入jar包。这种方式如果想用,还得在项目中已入依赖,这种方式是不行的。

引用方法:在项目下创建个文件夹(一般都会命名为lib,这个可以随意定),然后把jar包放在该文件加下,如图2.3。最后在pom文件中已入该jar包,如表2.1。

图2.3、jar放的位置

<dependency>

<groupId>com.bonc</groupId>

<artifactId>mcp-activiti-invoke</artifactId>

<version>0.0.1-SNAPSHOT</version>

<scope>system</scope>

<systemPath>${project.basedir}/src/main/resources/lib/mcp-activiti-invoke-0.0.1-SNAPSHOT.jar</systemPath>

</dependency>

表2.4、引入本地jar

这种打包方式用第一种引用可以,用第二种不行。如果B项目想用A项目打的包,我只需要把A的包引入就可以,不需要考虑A的依赖。为了解决这个问题,我又找到了第三种方式。

3、Assembly插件打包

为了解决A项目打的包直接可以放在B项目中用,在B用A项目打的包的时候不需要考虑A项目中的依赖,我找到了这种打包方式。

<build>

<plugins>

<plugin>

<groupId>org.apache.maven.plugins</groupId>

<artifactId>maven-assembly-plugin</artifactId>

<version>3.1.1</version>

<configuration>

<encoding>UTF-8</encoding>

<descriptorRefs>

<descriptorRef>jar-with-dependencies</descriptorRef>

</descriptorRefs>

<archive>

<manifest>

<mainClass>com.bonc.activitiinvoke.McpActivitiInvokeApplication</mainClass>

</manifest>

</archive>

</configuration>

<executions>

<execution>

<id>make-assembly</id>

<phase>package</phase>

<goals>

<goal>single</goal>

</goals>

</execution>

</executions>

</plugin>

</plugins>

</build>

表3.1、引入assembly插件

然后点击idea左边的Maven Project->你的项目名->Lifecycle->instal就会把这个项目放入你本地的Maven库,而且还会在你的项目下生成一个jar包。如图:

图3.1、打包过程

图3.2、生成的jar包

这种方式打的包利用坐标引入本地库的依赖和引入本地的jar都可以。引用方式同上。

4、打包的时候剔除不想要的依赖

当我们在打包的时候,有些依赖我们只想测试的时候后,打包的时候不想打入包中,

例;

我创建的项目是springboot的,会有springboot依赖,当掉我这个包的项目也是springboot项目,但是这两个springboot版本不一样。这时候如果我把springboot相关的依赖打入包中的时候,引用我的项目就可能包冲突,启动不起来。如果引入方式的时候引入的是从本地仓库中引用的话,那么我们还可以采用依赖排除。但是打入jar包中的我们不能排除(注;这种我试了,没有排除掉。我只是按我操作结果写的,也不知道对不对。如果不对请指正)。此时我就想打包的时候可以不把springboot相关依赖打入包中,把其他的依赖打入包中。

在引入依赖的时候,有个属性scope,叫作用。它对应的属性值有:


compile




是默认的范围;如果没有提供一个范围,那该依赖的范围就是编译范围。编译范围依赖在所有的classpath 中可用,同时它们也会被打包。


provided




依赖只有在当JDK 或者一个容器已提供该依赖之后才使用。例如, 如果你开发了一个web 应用,你可能在编译 classpath 中需要可用的Servlet API 来编译一个servlet,但是你不会想要在打包好的WAR 中包含这个Servlet API;这个Servlet API JAR 由你的应用服务器或者servlet 容器提供。已提供范围的依赖在编译classpath (不是运行时)可用。它们不是传递性的,也不会被打包。


runtime:

依赖在运行和测试系统的时候需要,但在编译的时候不需要。比如,你可能在编译的时候只需要JDBC API JAR,而只有在运行的时候才需要JDBC驱动实现。


test:

范围依赖在一般的编译和运行时都不需要,它们只有在测试编译和测试运行阶段可用。


system




范围依赖与provided 类似,但是你必须显式的提供一个对于本地系统中JAR 文件的路径。这么做是为了允许基于本地对象编译,而这些对象是系统类库的一部分。这样的构件应该是一直可用的,Maven 也不会在仓库中去寻找它。如果你将一个依赖范围设置成系统范围,你必须同时提供一个 systemPath 元素。注意该范围是不推荐使用的(你应该一直尽量去从公共或定制的 Maven 仓库中引用依赖)。

我们可以把依赖的坐标设置为provided,这样打包的时候就不会打入包中。

注:自己按经验而写,如有不对请指正。谢谢。



版权声明:本文为weixin_38903248原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。