Java module

模块的主要作用有:

  • 模块间需要显示地声明(模块)依赖,而不是以前的简单的基于 classpath
  • 更强的封装隔离,模块不主动导出的话无法被 import
    ;不
    open
    则无法对其使用反射技术

指令

模块通过在模块根目录下的中 module-info.java
的指令来约束使用。

定义模块

最好(或则是必须,没找到规定说明) moduleName
和文件夹名称一致,否则
 
javac

编译时提示 module
和预期的不一致

module moduleA {

}

引入依赖

requires moduleB;

可加
transitive
来表示依赖传递,如
requires transitive moduleB;
,然后在
moduleC
requires moduleA;
后,那么在
moduleC 中可使用在
moduleB 中导出的类或接口。


导出
package

exports packageFullName;

表示当别的模块(
A
requires 了当前模块,那么
packageFullName 这个包(及子孙包)里的
public
protected 的类和接口可在模块
A 里被访问使用。

可用
exports packageFullName to moduleA, moduleB;
来表示仅
moduleA
moduleB 可访问
packageFullName

提供服务

provides full.name.Service with full.name.concreateService, full.name.concreateService2;

表示该模块向外提供
full.name.Service
的实现
full.name.concreateService

full.name.concreateService2

使用服务

uses full.name.Service;

表示该模块需要使用 full.name.Service
。同时,不直接依赖具体的实现,而是使用抽象类或接口。然后搭配 ServiceLoader
或别的 IoC
工具来做依赖注入,从而达到和具体实现解耦的目的。

配合反射

opens fullPackageName;

表示
fullPackageName
可被使用反射技术。也可使用
opens fullPackageName to moduleA, moduleB;
限定开放反射的范围。

open module moduleD {};
表示整个模块都是开放的。

其它

java --list-modules
查看
JDK 内置的模块

编译运行

可通过
javac -d mods --module-source-path src $(find src -name "*.java")
来编译运行(多个模块),
src 表示各模块所在的目录。

也可使用
javac -d dist --module-source-path src -m client
来编译指定的模块。

示例代码

src

├── sample.client

│   ├── module-info.java

│   └── test

│       └── client

│           └── Main.java

├── sample.impl

│   ├── module-info.java

│   └── test

│       └── impl

│           └── AccessImpl.java

├── sample.model

│   ├── module-info.java

│   └── test

│       └── model

│           └── Person.java

└── sample.service

    ├── module-info.java

    └── test

        └── service

            └── AccessService.java

sample.model/module-info.java

module sample.model {
    exports test.model;
    opens test.model;
}

sample.model/test/model/Person.java

package test.model;

public class Person {
    private String name;

    public Person(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Person{name='" + name + "'}";
    }

    public static void main(String args[]) {
        System.out.println("Person main");
    }
}

sample.service/module-info.java

module sample.service {
    requires transitive sample.model;
    exports test.service;
}

sample.service/test/service/AccessService.java

package test.service;

import test.model.Person;

public interface AccessService {
    String getName(Person person);
}

sample.impl/module-info.java

module sample.impl {
    requires sample.service;
    provides test.service.AccessService with test.impl.AccessImpl;
}

sample.impl/test/impl/AccessImpl.java

package test.impl;

import test.model.Person;
import test.service.AccessService;

import java.lang.reflect.Field;

public class AccessImpl implements AccessService {
    @Override
    public String getName(Person person) {
        try {
            return extract(person);
        } catch (Exception e) {
            throw  new RuntimeException(e);
        }
    }

    private String extract(Person person) throws Exception {
        Field field = person.getClass().getDeclaredField("name");
        field.setAccessible(true);
        return (String) field.get(person);
    }
}

sample.client/module-info.java

module sample.client {
    requires sample.service;
    uses test.service.AccessService;
}

sample.client/test/client/Main.java

package test.client;

import test.model.Person;
import test.service.AccessService;

import java.util.ServiceLoader;

public class Main {
    public static void main(String[] args) {
        AccessService service = ServiceLoader
                .load(AccessService.class)
                .findFirst()
                .get();

        Person person = new Person("John Doe");
        String name = service.getName(person);

        assert name.equals("John Doe");
        System.out.println(person);
    }
}

注意事项

IDEA 中,由于本身有一个
module 的概念,搭配使用
Java
module 时,一个
IDEA
module 只能定义一个
module-info.java

参考

  • Understanding Java 9 Modules
  • The State of the Module System
  • Support for Java 9 Modules in IntelliJ IDEA 2017.1

原文 

https://liunian.info/java-module.html

本站部分文章源于互联网,本着传播知识、有益学习和研究的目的进行的转载,为网友免费提供。如有著作权人或出版方提出异议,本站将立即删除。如果您对文章转载有任何疑问请告之我们,以便我们及时纠正。

PS:推荐一个微信公众号: askHarries 或者qq群:474807195,里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多

转载请注明原文出处:Harries Blog™ » Java module

分享到:更多 ()

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址