java9学习之模块化
截止到目前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学习之模块化的更多相关文章
- Java9 modules (Jigsaw)模块化迁移
要点 通过模块化的方式开发应用程序,实现更好的设计,如关注点分离和封装性. 通过Java平台模块化系统(JPMS),开发者可以定义他们的应用程序模块,决定其他模块如何调用他们的模块,以及他们的模块如何 ...
- ES6-11学习笔记--模块化
模块化规范有: CommonJS:Node.js AMD:require.js CMD:sea.js ES6:Module ES6模块化使用: 关键词:export.import.as.exp ...
- laravel学习:模块化caffeinated
# Modules Extract and modularize your code for maintainability. Essentially creates "mini-larav ...
- nodeJs学习-06 模块化、系统模块、自定义模块、express框架
系统模块:http://nodejs.cn/api/events.html 自定义模块: require 请求:引入模块 module 模块:批量输出 exports 输出:单独输出 ...
- JAVA9模块化详解(一)——模块化的定义
JAVA9模块化详解 前言 java9已经出来有一段时间了,今天向大家介绍一下java9的一个重要特性--模块化.模块化系统的主要目的如下: 更可靠的配置,通过制定明确的类的依赖关系代替以前那种易错的 ...
- Java 9 模块化(Modularity)
JDK9的发布一直在推迟,终于在2017年9月21日发布了.下面是JDK9的几个下载地址: JDK9.0.1 Windows-x64下载地址 Oracle Java 官网下载地址 OpenJDK 9官 ...
- selenium + python自动化测试unittest框架学习(一)selenium原理及应用
unittest框架的学习得益于虫师的<selenium+python自动化实践>这一书,该书讲得很详细,大家可以去看下,我也只学到一点点用于工作中,闲暇时记录下自己所学才能更加印象深刻. ...
- ES6模块化使用遇到的问题
前言 最近在学习ES6模块化时,遇到了一些问题,通过查询相关资料得以解决,本篇随笔详细记录了解决方法. 具体内容 以下定义一个模块common.js 在test.html中引入上述定义的模块 运行上述 ...
- Python深度学习 deep learning with Python
内容简介 本书由Keras之父.现任Google人工智能研究员的弗朗索瓦•肖莱(François Chollet)执笔,详尽介绍了用Python和Keras进行深度学习的探索实践,涉及计算机视觉.自然 ...
随机推荐
- 【iOS】swift-Binary operator '|' cannot be applied to two UIViewAutoresizing operands
let view = UIView(frame: CGRect(x: 0, y: 0, width: 320, height: 568)) addSubview(view) view.autoresi ...
- BAT齐聚阿里安全-ASRC生态大会:呼吁联合共建网络安全白色产业链
图说:近日,阿里安全-ASRC生态大会在杭州举行,包括BAT在内的20余家国内知名互联网企业代表,回顾过去一年网络安全面临的问题与挑战,共谋生态安全治理思路. "123456.111111. ...
- python 单例模式的四种创建方式
单例模式 单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在.当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场. ...
- JWT(JSON Web Token) 多网站的单点登录,放弃session
多个网站之间的登录信息共享, 一种解决方案是基于cookie - session的登录认证方式,这种方式跨域比较复杂. 另一种替代方案是采用基于算法的认证方式, JWT(json web token) ...
- GET和POST两种基本请求方法的区别
文章来源:http://www.cnblogs.com/logsharing/p/8448446.html GET和POST是HTTP请求的两种基本方法,要说它们的区别,接触过WEB开发的人都能说出一 ...
- python/数据库操作补充—模板—Session
python/数据库操作补充—模板—Session 一.创建一个app目录 在models.py只能类进行进行创建表 class Foo: xx= 字段(数据库数据类型) 字段类型 字符串 Email ...
- Linux平台部署.Net Core SDK
根据微软MSDN,.Net Core无论是1.x还是2.0都只支持64位系统. 准备 以下是.NetCore支持的系统版本 以下 Linux 64 位(x86_64 或 amd64)发行版本/版本支持 ...
- JS中的递归
递归基础 递归的概念 在程序中函数直接或间接调用自己 直接调用自己 简介调用自己 跳出结构,有了跳出才有结果 递归的思想 递归的调用,最终还是要转换为自己这个函数 如果有个函数foo,如果他是递归 ...
- Java中的变量数据类型补充
Java中变量的数据类型的补充 变量按照数据类型进行分类 1.基本数据类型 数值型:①整数类型(byte,short,int,long)②浮点型(float,doubbe)③字符型(char)④布尔型 ...
- vue基础特性
在这里我们主要是讲解一些vue实例的属性和一些基础的指令 vue实例属性: 其实和我们之前所学的对象的属性是相似的东西 vue的基础指令: 对于指令,大家可能之前么有接触过相关的概念,其实大家可以这样 ...