序
本文主要研究下如何在maven里頭構建java9 multi module及service實例
maven
整個工程跟傳統maven多module的工程結構一樣,java9的一個module對應maven project的一個module。下面是根目錄下的pom文件:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
<? 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-sort
這個是service接口module
1
2
3
4
|
module service.sort { exports service.sort; uses service.sort.SortService; } |
這里同時聲明uses SortService表示是它需要在這個module里頭使用ServiceLoader去加載service實例
1
2
3
4
5
6
7
8
9
10
11
12
13
|
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實例。
service-sort-bubble
maven
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
<? 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-info.java
1
2
3
4
|
module service.sort.bubble { requires service.sort; provides service.sort.SortService with sort.impl.bubble.BubbleSort; } |
這里聲明了BubbleSort提供了SortService的實現
BubbleSort
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
<? 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
1
2
3
4
|
module service.sort.merge { requires service.sort; provides service.sort.SortService with sort.impl.merge.MergeSort; } |
這里聲明了MergeSort為SortService接口的實現
MergeSort
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
<? 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
1
2
3
|
module consumer { requires service.sort; } |
Main
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
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" ); } } |
編譯及運行
編譯
1
|
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那種聲明方式。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。
原文鏈接:https://juejin.im/post/5a9269c85188257a84625450