使用maven构建java9 service实例

本文主要研究下如何在maven里头构建java9 multi module及service实例

maven

整个工程跟传统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-sort

这个是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实例。

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包的依赖

  • module-info.java module service.sort.bubble { requires service.sort; provides service.sort.SortService with sort.impl.bubble.BubbleSort; } 这里声明了BubbleSort提供了SortService的实现
  • 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接口的实现
  • 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

  • Slim modular Java 9 runtime Docker image with Alpine Linux
  • 如何在Maven项目中设置Java 9

原文发布于微信公众号 - 码匠的流水账(geek_luandun)

原文发表时间:2018-02-25

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏菩提树下的杨过

利用sharding-jdbc分库分表

sharding-jdbc是当当开源的一款分库分表的数据访问层框架,能对mysql很方便的分库、分表,基本不用修改原有代码,只要配置一下即可,完整的配置参考以下...

36070
来自专栏软件工程师成长笔记

spring boot--Deferred方式实现异步调用,提高系统的吞吐量

在我们的实际生产中,常常会遇到下面的这种情况,某个请求非常耗时(大约5s返回),当大量的访问该请求的时候,再请求其他服务时,会造成没有连接使用的情况,造成这种现...

37220
来自专栏Java帮帮-微信公众号-技术文章全总结

JSP简单入门(1)

JSP页面中可以包含模板元素、脚本元素、EL表达式、注释、指令、和行为元素(JSP标签)等内容。有三种类型的脚本元素:JSP脚本片断、JSP表达式和JSP声明,...

453110
来自专栏Java架构沉思录

如何优雅实现优雅停机?

其实优雅停机,就是在要关闭服务之前,不是立马全部关停,而是做好一些善后操作,比如:关闭线程、释放连接资源等。

21010
来自专栏Jed的技术阶梯

Kafka 新版消费者 API(三):以时间戳查询消息和消费速度控制

kafka 在 0.10.1.1 版本增加了时间索引文件,因此我们可以根据时间戳来访问消息。 如以下需求:从半个小时之前的offset处开始消费消息,代码示例...

2.5K20
来自专栏LanceToBigData

JavaWeb(三)JSP之3个指令、6个动作、9个内置对象和4大作用域

前言   前面大概介绍了什么是JSP,今天我给大家介绍一下JSP的三个指令、6个动作以及它的9大内置对象。接下来我们就直接进入正题 一、JSP的3个指令 JSP...

31670
来自专栏闵开慧

hadoop源码解析2 - conf包中Configuration.java解析

1 Hadoop Configuration简介     Hadoop没有使用java.util.Properties管理配置文件,也没有使用Apache Ja...

34780
来自专栏木木玲

Netty 源码解析 ——— ChannelConfig 和 Attribute

27820
来自专栏chenssy

哦,这就是java的优雅停机?(实现及原理)

其实优雅停机,就是在要关闭服务之前,不是立马全部关停,而是做好一些善后操作,比如:关闭线程、释放连接资源等。

16320
来自专栏机器学习从入门到成神

在MyEclipse中使用Junit 的方法

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sinat_35512245/articl...

10810

扫码关注云+社区

领取腾讯云代金券