Spring Boot项目作为可导入依赖JAR包的构建指南

本文旨在解决spring boot项目在作为其他项目的依赖库时,默认打包方式(含boot-inf目录)不兼容的问题。通过结合使用maven assembly插件生成包含所有依赖的jar包,并巧妙配置spring boot maven插件以跳过其默认行为,我们将指导您构建一个标准、自包含且可被其他项目轻松导入的jar文件,同时提供详细的配置示例和注意事项。

引言:Spring Boot项目作为库的挑战

Spring Boot项目通常使用spring-boot-maven-plugin来打包成可执行的“胖JAR”(Fat JAR)。这种JAR包包含所有项目代码、资源以及其所有依赖,并具有一个特殊的BOOT-INF目录结构,其中包含了应用程序的类和依赖库。这种结构非常适合独立运行的应用程序,但当您尝试将此类JAR作为另一个Maven或Gradle项目的依赖项导入时,通常会遇到问题,因为其内部结构不符合标准的库JAR规范,导致类加载或依赖解析失败。

为了解决这个问题,开发者有时会尝试使用maven-assembly-plugin并配置jar-with-dependencies描述符。然而,如果spring-boot-maven-plugin仍然处于活跃状态,它可能会干扰Assembly插件的输出,导致生成两个JAR包:一个不包含依赖的标准JAR,以及一个仍然带有BOOT-INF结构的JAR,或者一个虽然包含依赖但结构不理想的JAR。本教程将展示如何正确配置,以生成一个单一的、自包含且可导入的库JAR。

核心策略:生成自包含的依赖JAR

要成功地将Spring Boot项目打包为可导入的依赖库,核心策略是:利用Maven Assembly插件来聚合所有依赖,同时禁用或跳过Spring Boot Maven插件的默认打包行为

1. 配置Maven Assembly插件

maven-assembly-plugin是Maven社区中用于创建自定义打包文件的强大工具。通过使用jar-with-dependencies描述符,它可以将项目的所有编译类和其所有运行时依赖项打包到一个单一的JAR文件中。

在项目的pom.xml文件中,添加以下配置:


    
        
            maven-assembly-plugin
            3.4.2 
            
                
                    jar-with-dependencies
                
                
                    
                        true
                        true
                    
                
            
            
                
                    make-assembly
                    package
                    
                        single
                    
                
            
        
    

解释:

  • jar-with-dependencies:这是关键部分,它告诉Assembly插件使用预定义的jar-with-dependencies策略来打包,即将所有依赖项包含在最终的JAR中。
  • ...:可选配置,用于在JAR的MANIFEST.MF文件中添加实现和规范信息,有助于识别库版本。
  • :配置插件在Maven生命周期的package阶段执行single目标,从而生成Assembly JAR。

2. 跳过Spring Boot Maven插件

spring-boot-maven-plugin是Spring Boot项目默认用于构建可执行JAR的插件。它的默认行为会生成带有BOOT-INF目录的JAR,这正是我们作为库使用时需要避免的。为了防止它干扰Assembly插件或生成不必要的额外JAR,我们需要明确地跳过它的执行。

在pom.xml的部分,找到spring-boot-maven-plugin的配置(如果它存在,通常由Spring Boot Starter Parent引入),并添加true


    
        
            org.springframework.boot
            spring-boot-maven-plugin
            
                true 
            
        
        
    

解释:

  • true:这个配置项指示spring-boot-maven-plugin在Maven构建过程中不执行其任何目标,从而避免生成可执行的Spring Boot JAR及其特有的BOOT-INF结构。

3. 移除不必要的Spring Boot启动类

当项目被用作一个库时,它不再需要一个main方法来启动自身。因此,包含@SpringBootApplication注解和SpringApplication.run()调用的启动类变得多余。移除这些代码可以使项目更纯粹地作为库存在,并避免潜在的混淆。

例如,如果您的项目中有一个类似以下的类:

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

您可以安全地将其删除,或者至少移除main方法和@SpringBootApplication注解,将其转换为一个普通的配置类或组件类,如果它承载了其他业务逻辑。

完整的pom.xml配置示例

结合上述所有更改,您的pom.xml的部分应如下所示:



    4.0.0

    
        org.springframework.boot
        spring-boot-starter-parent
        2.7.18 
         
    

    com.example
    my-spring-boot-library
    0.0.1-SNAPSHOT
    jar 

    
        11
    

    
        
        
            org.springframework.boot
            spring-boot-starter
        
        
    

    
        
            
            
                maven-assembly-plugin
                3.4.2 
                
                    
                        jar-with-dependencies
                    
                    
                        
                            true
                            true
                        
                    
                
                
                    
                        make-assembly
                        package
                        
                            single
                        
                    
                
            

            
            
                org.springframework.boot
                spring-boot-maven-plugin
                
                    true
                
            
        
    

构建与验证

完成pom.xml的修改后,您可以通过以下Maven命令进行构建:

mvn clean package

执行此命令后,在项目的target目录下,您将找到一个名为my-spring-boot-library-0.0.1-SNAPSHOT-jar-with-dependencies.jar(名称会根据您的artifactId和version变化)的JAR文件。这个JAR文件将包含您项目的所有编译类以及其所有传递性依赖,并且没有BOOT-INF目录结构,可以直接作为普通库依赖导入到其他项目中。

注意事项

  • 适用场景:此方法主要适用于将Spring Boot项目作为“库”而不是独立“应用程序”来发布和使用。如果您需要同时发布一个可执行JAR和一个库JAR,您可能需要更复杂的Maven配置文件,例如使用Maven Profiles来区分构建目标。
  • 依赖冲突:尽管jar-with-dependencies会把所有依赖打包进去,但在消费此库的项目中,仍然需要注意潜在的依赖版本冲突。如果消费项目和库项目依赖了同一个库的不同版本,可能会导致运行时问题。
  • 瘦JAR与胖JAR:此方法生成的JAR是一个“胖JAR”,它包含了所有项目依赖。在某些情况下,如果消费项目已经包含了大部分共享依赖,您可能希望生成一个“瘦JAR”(只包含项目自身的类),然后

    让消费项目来管理所有依赖。这可以通过移除maven-assembly-plugin并确保packaging为jar,但要手动在消费项目中声明所有传递性依赖来实现。然而,对于希望简单导入一个自包含库的场景,胖JAR通常更方便。

总结

通过本教程,您应该已经掌握了如何将一个Spring Boot项目成功打包成一个标准的、包含所有依赖的JAR文件,使其能够作为其他项目的依赖库来使用。关键在于理解spring-boot-maven-plugin的默认行为,并通过maven-assembly-plugin来生成目标JAR,同时禁用Spring Boot插件的打包过程。遵循这些步骤,将有助于您更灵活地管理和重用Spring Boot模块。