使用maven构建java9 service实例

Posted 码匠的流水账

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用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

以上是关于使用maven构建java9 service实例的主要内容,如果未能解决你的问题,请参考以下文章

java9学习之模块化

如何在 Eclipse Oxygen 中将 log4j 与 maven 和 java9 一起使用?

由于缺少 tools.jar,Maven AspectJ 插件无法使用 Java 9 构建

Maven “Failed to execute goal org.apache.maven.plugins:maven-archetype-plugin:2.4:create...”问题总结(示例代

如何正确地实现Java模块与inter-module Maven构建测试依赖关系

Java 9 中的 Maven 更新,Eclipse 中的 Java 8 中的 Maven 编译