1. 程式人生 > >springboot2.0+dubbo-spring-boot-starter聚合項目打可執行的jar包

springboot2.0+dubbo-spring-boot-starter聚合項目打可執行的jar包

inf 惡心 class int reg spa 打包成 tco public

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

springboot2.0+dubbo-spring-boot-starter聚合項目打可執行的jar包