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

    xiaoxiao2022-07-04  112

    假如有两个项目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,这样打包的时候就不会打入包中。

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

    最新回复(0)