zoukankan      html  css  js  c++  java
  • springboot2.0+dubbospringbootstarter聚合项目打可执行的jar包

    springboot2.0+dubbo聚合项目打可执行的jar包

    springboot2.0+dubbo-spring-boot-starter项目服务方打包和以前老版本的dubbo打包方式不一样,不需要将dubbo的配置文件放到META-INF下的spring文件夹中,和普通的springboot项目打包相似。

    一般dubbo项目都是聚合形式的,下面看一下springboot+dubbo-spring-boot-starter聚合打可执行的jar:

    一、spring-boot-maven-plugin打包出来的jar是不可依赖的

    列如我有一个parent工程,type为pom,下面两个spring-boot工程作为它的module,分别为moduleA和moduleB。假如moduleA依赖于moduleB。如果你在moduleB中使用了spring-boot-maven-plugin的默认配置build,或者在root中使用spring-boot-maven-plugin的默认配置build。很遗憾,你在clean package的时候会发现moduleA找不到moduleB中的类。原因就是默认打包出来的jar是不可依赖的。

    解决方案:

    1、调整你的代码,把spring-boot的东西从moduleB中移走,但是这么干是不可能的。

    2、官方告诉我们,你如果不想移代码,好吧,我这样来给你解决,给你打两个jar包,一个用来直接执行,一个用来依赖。于是,你需要指定一个属性classifier,这个属性为可执行jar包的名字后缀。比如我设置exec,原项目名为Vehicle-business。那么我会得到两个jar:Vehicle-business.jar和Vehicle-bussiness-exec.jar

    官方文档位置:84.5 Use a Spring Boot application as a dependency

    总结:回到聚合maven上,如果你在parent工程中使用了spring-boot-maven-plugin作为builder,那么你的依赖module一定要用解决方案二来设置。否则你不在root工程中用spring-boot-maven-plugin作为builder,而在需要打包的module上使用。

    二、jdk8一定要指明

    不指明的话在开发工具里运行没有一点问题,如果你没有用到java8的特性打包也没有问题。一旦你用到了java8的特性,而且使用spring-boot-maven-plugin作为builder,一定要指明jdk版本。不然你会收到类似不识别Lambda,请使用resource8这样的错误。

    <properties>
        <java.version>1.8</java.version>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
      </properties>

    三、BOOT-INF陷阱

    这个问题就很恶心了。这个时候你已经打包成功,你会发现运行jar的时候报错为file not found,而且不告诉你是什么文件。你打开jar去看,发现需要的lib,配置文件,class一样也不缺。

    其实这里要说一个概念,spring-boot在打包后,会把文件拷贝到BOOT-INF/Classes之下,这个时候你原来定义的扫描包路径将失效。而这个问题官方文档根本没讲,还是我没有看到。

    这个陷阱在你使用packages定义扫描路径的时候等着你。或者获取工程下文件的时候。对于获取文件的话,可以在原路径前加上classes,当然你要区分开发环境或生产环境的话,你可以使用profile或者conditional来解决。如果是扫描包路径就恶心了,因为你加上classes之后,不报file not found了。而是不报错,只是警告你找不到hibernate的某些xml。但是你很可能根本没有使用hibernate。

    目前我的解法是使用register方法代替packages方法,但是问题就是,如果你的类很多,那将是一件痛苦的事情。还好我这里只需要配置两个基于jersey的公共类。

    顺便吐槽一下官方文档在配置jersey的时候根本没有提到packages方法,自然也就把这个BOOT-INF陷阱给忽略了。官方关于jersey的配置章节为27.2 JAX-RS and Jersey

    假设工程结构如下:

    parent
      moduleA
      moduleB
      moduleC
    

    其中moduleB被moduleA依赖,A使用jersey,moduleA和moduleC需要打包为可执行jar 
    那么我们有两种方式聚合

    方式一 在parent中指定spring-boot-maven-plugin

    parent的pom.xml中的builder

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                 <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
      </build>

    moduleB的pom.xml中的builder

     <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <classifier>exec</classifier>
                </configuration>
            </plugin>
        </plugins>
    </build>

    其余工程不需要builder

    方法二 parent的pom.xml不提供builder

    moduleA和moduleC的pom.xml中的builder

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                 <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
      </build>

    最后,两种方法都需要把jersey配置文件中的packages方法换成register方法

    public class JerseyConfig extends ResourceConfig{
        public JerseyConfig() {
           register(RequestContextFilter.class);
           //配置restful package.
           //packages("com.zs.vehicle.rpc");
           //packages("classes/com/zs/vehicle/rpc");
           register(Base.class);
           register(Route.class);
        }
    }

    运行maven命令:

     mvn clean package

  • 相关阅读:
    再探最大公约数
    非旋treap
    初赛毒瘤汇总(持续更新中)
    架构漫谈阅读笔记五--以豆瓣得基础架构为例
    架构设计小论文
    第一阶段
    架构漫谈阅读笔记六--以淘宝数据魔方技术架构解析为例
    学习进度第八周
    架构漫谈阅读笔记一
    软件架构之 Refined Architecture阶段
  • 原文地址:https://www.cnblogs.com/typ1805/p/9311336.html
Copyright © 2011-2022 走看看