截止到目前JDK的版本已经更新到10了,虽然java9的生命周期才半年,但是我认为这个版本带来的变革是不可磨灭的,它是第一次深层次的针对架构以及依赖上的革新。下面我们就来学习一下。

一、模块化项目构建

  其实模块化本身不难理解,我们先前使用maven或者gradle就构建过多模块的项目。那么我们在java9里依然可以照猫画虎来构建一下我们的模块化项目工程。如图所示:

注意以下几点:

  1.请在每个模块下创建一个叫做module-info.java的模块化描述文件

  2.在idea里配置一下模块依赖,在这里我们的project.portal模块如果依赖student.service模块,我们可以这么来设置:

  找到这个选项图标:,然后这样设置来添加依赖:

  

  如果需要设置其他项目的依赖项,也请按照此方式设置。

二、实现步骤

2.1、Student.Service模块

2.1.1、编写StudentService的module-info.java

示例代码:

import com.bdqn.lyrk.student.service.SecondStudentService;
import com.bdqn.lyrk.student.service.api.IStudentService;
/**
* 模块化描述类,统一建立在各个模块的源文件根目录 名字为:module-info.java
* 模块化常见的语法结构:
*
* import xxxx.xxxx;
* ....
*
* [open] module 模块名 {
* requires [static|transitive] 模块名;
* exports 包名 [to 模块名]
* providers 接口名 with [接口实现类,....]
* uses 接口名
*
* }
*
*
* @author chen.nie
* @date 2018/4/18
**/
module student.service { exports com.bdqn.lyrk.student.service.api;
provides IStudentService with SecondStudentService;
}

2.1.2、定义接口

package com.bdqn.lyrk.student.service.api;

public interface IStudentService {
void study();
}

2.1.3、定义实现类

package com.bdqn.lyrk.student.service;

import com.bdqn.lyrk.student.service.api.IStudentService;

public class SecondStudentService implements IStudentService {
@Override
public void study() {
System.out.println("second study");
}
}

2.2、project.portal 模块

2.2.1、编写module-info.java

import com.bdqn.lyrk.student.service.api.IStudentService;

module project.portal {
uses IStudentService;
requires transitive student.service;
}

2.2.2、编写Main方法

package com.bdqn.lyrk.portal;

import com.bdqn.lyrk.student.service.api.IStudentService;

import java.util.ServiceLoader;

public class Main {
public static void main(String[] args) {
ServiceLoader<IStudentService> studentServices = ServiceLoader.load(IStudentService.class);
studentServices.findFirst().get().study();
}
}

我们运行后既可以拿到对应的结果:

三、module-info.java文件常见配置

3.1、关于open关键字

  open:该关键字如果加载模块上,那么通过exports的导出包下的类可见度是最高的,我们可以通过反射的方式来创建对对象和访问属性。

3.2、关于exports关键字

  当我们定义好模块后,我们可以指定该模块下的哪些包可以被其他模块所访问,exports关键字就起到该作用。我们也可以配合to来指定哪些模块可以访问该包的内容

  语法 exports 包名 [to] 模块名

exports <package>;
exports <package> to <module1>, <module2>...;

3.3、opens关键字

    opens类似于open,如果open关键字加在module上,那么模块里默认导出的exports包都为open形式的

module N {
exports com.jdojo.claim.model;
opens com.jdojo.claim.model;
}

3.4、requires关键字

该关键字声明当前模块与另一个模块的依赖关系。有点类似于maven中的dependecies。

requires <module>;
requires transitive <module>;
requires static <module>;
requires transitive static <module>;

  require语句中也可以加静态修饰符,这样的话表示在编译时的依赖是强制的,但在运行时是可选的。require语句中的transitive修饰符会导致依赖于当前模块的其他模块具有隐式依赖性,请看下图:

在这里我们可以看看java.se模块下的module-info.class文件:

/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/ /**
* Defines the core Java SE API.
* <P>
* The modules defining the CORBA and Java EE APIs are not required by
* this module, but they are required by the
* <a href="java.se.ee-summary.html">{@code java.se.ee}</a> module.
*
* <dl>
* <dt class="simpleTagLabel" style="font-family:'DejaVu Sans', Arial, Helvetica, sans serif">Optional for the Java SE Platform:</dt>
* <dd>
* <a href="../specs/jni/index.html">Java Native Interface (JNI)</a><br>
* <a href="../specs/jvmti.html">Java Virtual Machine Tool Interface (JVM TI)</a><br>
* <a href="../specs/jdwp/jdwp-spec.html">Java Debug Wire Protocol (JDWP)</a><br>
* </dd>
* </dl>
*
* @moduleGraph
* @since 9
*/
module java.se {
requires transitive java.compiler;
requires transitive java.datatransfer;
requires transitive java.desktop;
requires transitive java.instrument;
requires transitive java.logging;
requires transitive java.management;
requires transitive java.management.rmi;
requires transitive java.naming;
requires transitive java.prefs;
requires transitive java.rmi;
requires transitive java.scripting;
requires transitive java.security.jgss;
requires transitive java.security.sasl;
requires transitive java.sql;
requires transitive java.sql.rowset;
requires transitive java.xml;
requires transitive java.xml.crypto;
}

  此时我们只要requires java.se,那么该模块下的所有依赖我们就间接的引入了

3.5、uses与provider关键字

Java允许使用服务提供者和服务使用者分离的服务提供者机制。 JDK 9允许使用语句(uses statement)和提供语句(provides statement)实现其服务。使用语句可以指定服务接口的名字,当前模块就会发现它,使用 java.util.ServiceLoader类进行加载。代码请参考前面的例子,注意:provider提供的类必须在同一个模块下,当前不能引用其他模块的实现,比如说:前面的例子StudentServiceImpl只能存在student.service模块下,student.service模块provider其他的模块下的接口实现是不允许的。

java9学习之模块化的更多相关文章

  1. Java9 modules (Jigsaw)模块化迁移

    要点 通过模块化的方式开发应用程序,实现更好的设计,如关注点分离和封装性. 通过Java平台模块化系统(JPMS),开发者可以定义他们的应用程序模块,决定其他模块如何调用他们的模块,以及他们的模块如何 ...

  2. ES6-11学习笔记--模块化

    模块化规范有: CommonJS:Node.js AMD:require.js CMD:sea.js ES6:Module     ES6模块化使用: 关键词:export.import.as.exp ...

  3. laravel学习:模块化caffeinated

    # Modules Extract and modularize your code for maintainability. Essentially creates "mini-larav ...

  4. nodeJs学习-06 模块化、系统模块、自定义模块、express框架

    系统模块:http://nodejs.cn/api/events.html 自定义模块: require   请求:引入模块 module    模块:批量输出 exports   输出:单独输出   ...

  5. JAVA9模块化详解(一)——模块化的定义

    JAVA9模块化详解 前言 java9已经出来有一段时间了,今天向大家介绍一下java9的一个重要特性--模块化.模块化系统的主要目的如下: 更可靠的配置,通过制定明确的类的依赖关系代替以前那种易错的 ...

  6. Java 9 模块化(Modularity)

    JDK9的发布一直在推迟,终于在2017年9月21日发布了.下面是JDK9的几个下载地址: JDK9.0.1 Windows-x64下载地址 Oracle Java 官网下载地址 OpenJDK 9官 ...

  7. selenium + python自动化测试unittest框架学习(一)selenium原理及应用

    unittest框架的学习得益于虫师的<selenium+python自动化实践>这一书,该书讲得很详细,大家可以去看下,我也只学到一点点用于工作中,闲暇时记录下自己所学才能更加印象深刻. ...

  8. ES6模块化使用遇到的问题

    前言 最近在学习ES6模块化时,遇到了一些问题,通过查询相关资料得以解决,本篇随笔详细记录了解决方法. 具体内容 以下定义一个模块common.js 在test.html中引入上述定义的模块 运行上述 ...

  9. Python深度学习 deep learning with Python

    内容简介 本书由Keras之父.现任Google人工智能研究员的弗朗索瓦•肖莱(François Chollet)执笔,详尽介绍了用Python和Keras进行深度学习的探索实践,涉及计算机视觉.自然 ...

随机推荐

  1. JUnit单元测试遇到的问题及解决思路

    JUnit是Java单元测试框架,我们在对开发的系统进行单元测试的时候,也遇到了如何测试多个测试用例的问题.  背景:我们的所有测试用例都保存在Excel文件中,该文件包含测试用例和预期输出.我们希望 ...

  2. ASP.NET Web API编程——路由

    路由过程大致分为三个阶段: 1)请求URI匹配已存在路由模板 2)选择控制器 3)选择操作 1匹配已存在的路由模板 路由模板 在WebApiConfig.Register方法中定义路由,例如模板默认生 ...

  3. 解决yii2中 Class yii/web/JsonParser does not exist, ReflectionException问题

    最近在调试RESTful API示例时,出现以下错误: { "name": "Exception", "message": "Cl ...

  4. 基于RNN的音频降噪算法 (附完整C代码)

    前几天无意间看到一个项目rnnoise. 项目地址: https://github.com/xiph/rnnoise 基于RNN的音频降噪算法. 采用的是 GRU/LSTM 模型. 阅读下训练代码,可 ...

  5. OAuth2.0学习(1-13)oauth2.0 的概念:资源、权限(角色)和scope

    mkk 关于资源的解释 : https://andaily.com/blog/?cat=19 resource用于将系统提供的各类资源进行分组管理, 每一个resource对应一个resource-i ...

  6. python 字符串 字节

    字符串 字节   a. 字符串转字节 1 2 key = "xxxx" bkey = bytes(key,encoding='utf-8') b. bytearray 数组 1 2 ...

  7. python——常用模块2

    python--常用模块2 1 logging模块 1.1 函数式简单配置 import logging logging.debug("debug message") loggin ...

  8. IIS进行URL重写

    一.Why? 1.先来讲一讲为什么我们要使用url重写这个东西 2.因为我学习的后端是nodejs,然后我发现nodejs一个非常让人难受的事,就是它监听端口不是80和443时,你访问网页需要输入端口 ...

  9. Ubuntu16.04系统下 解决“无法获得锁 /var/lib/dpkg/lock -open (11:资源暂时不可用)、无法锁定管理目录(/var/lib/dpkg/),是否有其他进程正占用它?”的方法

    在Ubuntu16.04下安装软件,例如:sudo apt-get install lrzsz时提示: 无法获得锁 /var/lib/dpkg/lock - open (11: 资源暂时不可用) 无法 ...

  10. [项目推荐] Corcel 让你在 WordPress 中使用 Laravel

    你想过可以在 WordPress 中使用 Laravel 或者任意一种 PHP 框架吗? Corcel 可以帮你实现! 开发网站应用就应该是快捷并有趣的.当然了,每个应用都会有它自己的需求和生命周期. ...