本文主要研究下如何在maven裏頭構建java9 multi module及service實例java
整個工程跟傳統maven多module的工程結構同樣,java9的一個module對應maven project的一個module。下面是根目錄下的pom文件:
<?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版本。
這個是service接口module
module service.sort { exports service.sort; uses service.sort.SortService; }
這裏同時聲明uses SortService表示是它須要在這個module裏頭使用ServiceLoader去加載service實例
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實例。
<?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包的依賴
module service.sort.bubble { requires service.sort; provides service.sort.SortService with sort.impl.bubble.BubbleSort; }
這裏聲明瞭BubbleSort提供了SortService的實現
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); } }
<?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 service.sort.merge { requires service.sort; provides service.sort.SortService with sort.impl.merge.MergeSort; }
這裏聲明瞭MergeSort爲SortService接口的實現
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; } }
<?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 consumer { requires service.sort; }
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
這裏是在根目錄下執行
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
輸出git
sort service consumer started. use BubbleSort [2, 3, 5, 8, 10] finish
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
輸出github
sort service consumer started. using MergeSort [2, 3, 5, 8, 10] finish
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
或者docker
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
輸出apache
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那種聲明方式。api