使用maven構建java9 service實例

本文主要研究下如何在maven裏頭構建java9 multi module及service實例java

maven

整個工程跟傳統maven多module的工程結構同樣,java9的一個module對應maven project的一個module。下面是根目錄下的pom文件:git

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>java9-service-demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <modules>
        <module>consumer-demo</module>
        <module>service-sort</module>
        <module>service-sort-bubble</module>
        <module>service-sort-merge</module>
    </modules>
    <packaging>pom</packaging>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <!--讓intellij可以正確編譯java9,否則總是變回使用1.5-->
        <maven.compiler.source>9</maven.compiler.source>
        <maven.compiler.target>9</maven.compiler.target>
    </properties>

    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.6.1</version>
                    <configuration>
                        <release>9</release>
                    </configuration>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>

</project>
複製代碼

這裏管理了一個maven-compiler-plugin,配置release爲9,由於java9支持multi release,能夠同時支持多個java版本,這裏編譯爲java9版本。github

service-sort

這個是service接口moduledocker

module service.sort {
    exports service.sort;
    uses service.sort.SortService;
}
複製代碼

這裏同時聲明uses SortService表示是它須要在這個module裏頭使用ServiceLoader去加載service實例apache

public interface SortService {
    public <T extends Comparable> List<T> sortList(List<T> list);

    public static SortService getProviderInstanceLazy() {
        Stream<Provider<SortService>> providers = ServiceLoader.load(SortService.class)
                .stream();
        //provider方法等到get的時候纔會實例化
        SortService service = providers.map(Provider::get)
                .findAny()
                .orElse(null);
        return service;
    }
}
複製代碼

這裏在聲明接口的同時,也增長了靜態方法,用於加載service實例。api

service-sort-bubble

  • maven
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>java9-service-demo</artifactId>
        <groupId>com.example</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>service-sort-bubble</artifactId>
    <packaging>jar</packaging>

    <dependencies>
        <dependency>
            <groupId>com.example</groupId>
            <artifactId>service-sort</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
    </dependencies>

</project>
複製代碼

這裏添加對api包的依賴bash

  • module-info.java
module service.sort.bubble {
    requires service.sort;
    provides service.sort.SortService with sort.impl.bubble.BubbleSort;
}
複製代碼

這裏聲明瞭BubbleSort提供了SortService的實現maven

  • BubbleSort
public class BubbleSort implements SortService {

    public <T extends Comparable> List<T> sortList(List<T> list) {
        System.out.println("use BubbleSort");
        for (int outer = 0; outer < list.size() - 1; outer++) {
            for (int inner = 0; inner < list.size()-outer-1; inner++) {
                if (list.get(inner).compareTo(list.get(inner + 1)) > 0)  {
                    swap(list, inner);
                }
            }
        }
        return list;
    }

    private <T> void swap(List<T>list, int inner) {
        T temp = list.get(inner);
        list.set(inner, list.get(inner + 1));
        list.set(inner + 1, temp);
    }
}
複製代碼

service-sort-merge

  • maven
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>java9-service-demo</artifactId>
        <groupId>com.example</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>service-sort-merge</artifactId>
    <packaging>jar</packaging>

    <dependencies>
        <dependency>
            <groupId>com.example</groupId>
            <artifactId>service-sort</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
    </dependencies>
</project>
複製代碼
  • module-info.java
module service.sort.merge {
    requires service.sort;
    provides service.sort.SortService with sort.impl.merge.MergeSort;
}
複製代碼

這裏聲明瞭MergeSort爲SortService接口的實現ide

  • MergeSort
import java.util.List;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Arrays;
import service.sort.SortService;

public class MergeSort implements SortService {

    public <T extends Comparable> List<T> sortList(List<T> list) {
        System.out.println("using MergeSort");
        Collections.sort(list);
        return list;
    }
}
複製代碼

consumer

  • maven
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>java9-service-demo</artifactId>
        <groupId>com.example</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>consumer-demo</artifactId>
    <packaging>jar</packaging>

    <dependencies>
        <dependency>
            <groupId>com.example</groupId>
            <artifactId>service-sort</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
    </dependencies>

</project>
複製代碼

注意這裏沒有添加實現類的依賴模塊化

  • module-info.java
module consumer {
    requires service.sort;
}
複製代碼
  • Main
public class Main {

    public static void main(String[] args) {

        System.out.println("sort service consumer started.");
        List<Integer> data = new ArrayList<Integer>();
        data.add(5);
        data.add(3);
        data.add(10);
        data.add(2);
        data.add(8);

        SortService sortService = SortService.getProviderInstanceLazy();
        if (sortService != null) {
            sortService.sortList(data);
        }
        System.out.println(data);
        System.out.println("finish");
    }
}
複製代碼

編譯及運行

  • 編譯
mvn clean install
複製代碼

這裏是在根目錄下執行

  • 使用bubble
java --module-path ./consumer-demo/target/consumer-demo-0.0.1-SNAPSHOT.jar:./service-sort/target/service-sort-0.0.1-SNAPSHOT.jar:./service-sort-bubble/target/service-sort-bubble-0.0.1-SNAPSHOT.jar --module consumer/consumer.Main
複製代碼

注意這裏添加了bubble的jar到module-path

輸出

sort service consumer started.
use BubbleSort
[2, 3, 5, 8, 10]
finish
複製代碼
  • 使用merge
java --module-path ./consumer-demo/target/consumer-demo-0.0.1-SNAPSHOT.jar:./service-sort/target/service-sort-0.0.1-SNAPSHOT.jar:./service-sort-merge/target/service-sort-merge-0.0.1-SNAPSHOT.jar --module consumer/consumer.Main
複製代碼

注意這裏添加了merge的jar到module-path

輸出

sort service consumer started.
using MergeSort
[2, 3, 5, 8, 10]
finish
複製代碼
  • 兩個service實現都添加
java --module-path ./consumer-demo/target/consumer-demo-0.0.1-SNAPSHOT.jar:./service-sort/target/service-sort-0.0.1-SNAPSHOT.jar:./service-sort-bubble/target/service-sort-bubble-0.0.1-SNAPSHOT.jar:./service-sort-merge/target/service-sort-merge-0.0.1-SNAPSHOT.jar --module consumer/consumer.Main
複製代碼

或者

java --module-path ./consumer-demo/target/consumer-demo-0.0.1-SNAPSHOT.jar:./service-sort/target/service-sort-0.0.1-SNAPSHOT.jar:./service-sort-merge/target/service-sort-merge-0.0.1-SNAPSHOT.jar:./service-sort-bubble/target/service-sort-bubble-0.0.1-SNAPSHOT.jar --module consumer/consumer.Main
複製代碼

輸出

sort service consumer started.
use BubbleSort
[2, 3, 5, 8, 10]
finish
複製代碼

發現貌似跟添加到path的順序沒有關係,即便把merge的jar包放在前面,也是使用bubble

小結

在java6的時候就已經有ServiceLoader了,不過那個時候是依賴在jar包的META-INF/services目錄下建立一個service接口全路徑名稱的文件,裏頭寫上實現類的全路徑名稱。java9對在引入模塊化後也支持在module-info.java裏頭聲明service的提供方和消費者信息,這樣模塊系統能夠支持ServiceLoader,不須要使用原來的META-INF那種聲明方式。

doc

相關文章
相關標籤/搜索