草庐IT

读Java实战(第二版)笔记13_Java模块系统

躺柒 2023-03-28 原文

1. Nicolai Parlog编写的The Java Module System

1.1. 推荐阅读

2. Jigsaw项目

2.1. 开发持续了将近十年

3. 关注点分离

3.1. separation of concern,SoC

3.2. 将单体的计算机程序分解为一个个相互独立的特性

4. 信息隐藏

4.1. information hiding

4.2. 要求设计时尽量隐藏实现的细节

4.2.1. 隐藏内部实现细节能帮你减少局部变更对程序其他部分的影响

4.2.2. 有效地避免变更传递

4.2.3. 与应用的其他部分没有任何耦合,对这段代码内部实现的更迭不会对应用的其他部分产生影响

4.3. 通过private关键字,借助编译器验证组件中的类是否封装良好

4.4. Java 9出现之前,编译器无法依据语言结构判断某个类或者包仅供某个特定目标访问

5. 模块

5.1. 具备内聚特质的一组代码,它与其他模块代码之间很少有耦合

5.2. 通过模块组织类,可以帮助你清晰地表示应用程序中类与类之间的可见性关系

5.3. Java的包并未从本质上支持模块化

6. Java9之前模块化的局限性

6.1. 有限的可见性控制

6.1.1. 希望一个包中的某个类或接口可以被另外一个包中的类或接口访问,那么只能将它声明为public

6.1.2. 增大了系统受攻击的可能性,因为更多的代码都暴露在了攻击面下

6.2. 类的路径

6.2.1. 对同一个类,无法指定到底使用类路径上的哪一个版本,因为根本无法通过路径指定版本

6.2.2. 类路径也不支持显式的依赖

6.2.2.1. “类路径地狱”问题导致我们很难对应用的依赖性进行分析

6.2.2.2. ClassNotFound Exception

6.2.3. Maven或者Gradle这样的构建工具可以帮助解决这一问题

7. 单体型的JDK

7.1. 无论你是否在你的应用中使用了CORBA,对CORBA的支持默认都打包在JDK之中

7.2. Java 8引入了精简配置(compact profile

7.3. sun.misc.Unsafe类

7.3.1. 设计之初并不期望被JDK之外的任何代码访问或使用

7.3.2. 这个类被好几个流行的类库(包括Spring、Netty、Mockito等)所使用

7.4. 导致很高的维护成本并限制了Java的演进

8. 开放服务网关协议

8.1. open service gateway initiative, OGSi

8.2. 最早提出于2000年,直到Java 9诞生,一直都是实现基于JVM的模块化应用的事实标准

8.3. OGSi认证支持的框架

8.3.1. Apache Felix

8.3.2. Equinox

8.4. OGSi与新的Java 9模块系统之间并不是完全互斥的

8.4.1. 只有小部分的重叠

8.4.2. 可以在同一个应用之中共存

8.4.3. OGSi所覆盖的范畴要大得多

8.5. OGSi中每一个bundle都有单独的类加载器

8.5.1. Jigsaw中每个应用仅使用一个类加载器

8.5.2. 解决版本选择问题并不是Java 9模块系统设计的出发点,所以它不支持版本

9. Java模块系统基础

9.1. 模块化是对抗软件腐臭的利器

9.1.1. 随着项目的不断演进,更多的内部实现被加入进来,这时封装和划分的价值就变得越来越明显

9.2. 命名

9.2.1. 互联网域名规范的逆序

9.2.2. 模块名应该与它导出的主要API的包名保持一致

9.3. Java 9的模块

9.3.1. 提供粒度更细的控制

9.3.1.1. 可以设定哪个类能够访问哪个类

9.3.1.2. 这种控制是编译期检查的

9.3.2. 位于模块路径上且没有提供module-info文件的JAR文件会被Java 9作为自动模块处理

9.3.3. Maven支持按照Java 9模块系统构建的应用

9.4. 模块中的所有内容都是被封装的

9.4.1. 模块系统使用白名单的方式帮助你进行更严格的封装控制

9.4.2. 显式地声明你愿意将哪些内容提供给别的模块访问

9.4.3. 避免你由于偶然的机会开放一些内部接口给外部使用,可能导致你的系统被攻破

9.5. exports子句

9.5.1. 它声明的这些包会变为公有类型,可以被其他模块访问和调用

9.6. exports to

9.6.1. 可以限制哪些用户能访问哪些导出的包

9.7. requires子句

9.7.1. 可以指定本模块对其他模块的依赖

9.7.2. 所有的模块都依赖于名叫java.base的平台模块

9.7.2.1. 不需要显式声明

9.8. open和opens

9.8.1. 能够让其他模块以反射的方式访问它所有的包

9.8.2. open限定符在模块的可见性方面没有特别的效果,唯一的作用就是允许对模块进行反射访问

9.9. uses和provides

9.9.1. 使用provides子句创建服务供应方,使用users子句创建服务消费者

有关读Java实战(第二版)笔记13_Java模块系统的更多相关文章

  1. ruby - 在 Ruby 中使用匿名模块 - 2

    假设我做了一个模块如下:m=Module.newdoclassCendend三个问题:除了对m的引用之外,还有什么方法可以访问C和m中的其他内容?我可以在创建匿名模块后为其命名吗(就像我输入“module...”一样)?如何在使用完匿名模块后将其删除,使其定义的常量不再存在? 最佳答案 三个答案:是的,使用ObjectSpace.此代码使c引用你的类(class)C不引用m:c=nilObjectSpace.each_object{|obj|c=objif(Class===objandobj.name=~/::C$/)}当然这取决于

  2. ruby-on-rails - Ruby net/ldap 模块中的内存泄漏 - 2

    作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代

  3. ruby-on-rails - 在混合/模块中覆盖模型的属性访问器 - 2

    我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah

  4. java - 等价于 Java 中的 Ruby Hash - 2

    我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/

  5. ruby - 当使用::指定模块时,为什么 Ruby 不在更高范围内查找类? - 2

    我刚刚被困在这个问题上一段时间了。以这个基地为例:moduleTopclassTestendmoduleFooendend稍后,我可以通过这样做在Foo中定义扩展Test的类:moduleTopmoduleFooclassSomeTest但是,如果我尝试通过使用::指定模块来最小化缩进:moduleTop::FooclassFailure这失败了:NameError:uninitializedconstantTop::Foo::Test这是一个错误,还是仅仅是Ruby解析变量名的方式的逻辑结果? 最佳答案 Isthisabug,or

  6. ruby - 获取模块中定义的所有常量的值 - 2

    我想获取模块中定义的所有常量的值:moduleLettersA='apple'.freezeB='boy'.freezeendconstants给了我常量的名字:Letters.constants(false)#=>[:A,:B]如何获取它们的值的数组,即["apple","boy"]? 最佳答案 为了做到这一点,请使用mapLetters.constants(false).map&Letters.method(:const_get)这将返回["a","b"]第二种方式:Letters.constants(false).map{|c

  7. ruby - 模块嵌套代码风格偏好 - 2

    我的假设是moduleAmoduleBendend和moduleA::Bend是一样的。我能够从thisblog找到解决方案,thisSOthread和andthisSOthread.为什么以及什么时候应该更喜欢紧凑语法A::B而不是另一个,因为它显然有一个缺点?我有一种直觉,它可能与性能有关,因为在更多命名空间中查找常量需要更多计算。但是我无法通过对普通类进行基准测试来验证这一点。 最佳答案 这两种写作方法经常被混淆。首先要说的是,据我所知,没有可衡量的性能差异。(在下面的书面示例中不断查找)最明显的区别,可能也是最著名的,是你的

  8. ruby-on-rails - 使用 config.threadsafe 时从 lib/加载模块/类的正确方法是什么!选项? - 2

    我一直致力于让我们的Rails2.3.8应用程序在JRuby下正确运行。一切正常,直到我启用config.threadsafe!以实现JRuby提供的并发性。这导致lib/中的模块和类不再自动加载。使用config.threadsafe!启用:$rubyscript/runner-eproduction'pSim::Sim200Provisioner'/Users/amchale/.rvm/gems/jruby-1.5.1@web-services/gems/activesupport-2.3.8/lib/active_support/dependencies.rb:105:in`co

  9. java - 从 JRuby 调用 Java 类的问题 - 2

    我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www

  10. java - 我的模型类或其他类中应该有逻辑吗 - 2

    我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我

随机推荐