本文主要研究下如何在maven裏頭構建java9 multi module及service實例java
整個工程跟傳統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接口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
<?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 service.sort.bubble {
requires service.sort;
provides service.sort.SortService with sort.impl.bubble.BubbleSort;
}
複製代碼
這裏聲明瞭BubbleSort提供了SortService的實現maven
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接口的實現ide
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
輸出
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
輸出
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
複製代碼
或者
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那種聲明方式。