Java 中文官方教程 2022 版(四十二)(3)

简介: Java 中文官方教程 2022 版(四十二)

Java 中文官方教程 2022 版(四十二)(2)https://developer.aliyun.com/article/1488229

最高分条目

策略文件中的最后一个条目授予HighScore 类权限。更具体地说,它授予由"chris"签名的代码权限,他创建并签署了这个类。要求类由"chris"签名确保当ExampleGame 调用这个类来更新用户的高分时,ExampleGame 确切知道它正在使用由"chris"实现的原始类。

要更新调用它的任何游戏的用户高分值,HighScore 类需要三个权限:

1. 读取"user.home"属性值的权限。

HighScore 类将用户的高分值存储在用户主目录中的.highscore文件中。因此,这个类需要一个java.util.PropertyPermission,允许它读取"user.home"属性值,以确定用户主目录的确切位置:

permission java.util.PropertyPermission 
    "user.home", "read";

2. 读写高分文件本身的权限。

这个权限是为了让HighScoregetHighScoresetHighScore 方法可以访问用户的.highscore文件,分别获取或设置当前游戏的当前高分。

这是所需的权限:

permission java.io.FilePermission
    "${user.home}${/}.highscore", "read,write";

注意:${propName} 表示属性的值。因此,${user.home} 将被"user.home"属性的值替换。${/} 表示文件分隔符的平台无关方式。

3. 所有 HighScorePermissions(即任何名称的 HighScorePermissions)。

这个权限是为了确保HighScore 检查调用游戏是否被授予了一个名为游戏名称的HighScorePermission。也就是说,HighScore 类必须同样被授予权限,因为权限检查要求堆栈上的所有代码都具有指定的权限。

这是所需的权限:

permission com.scoredev.scores.HighScorePermission
    "*", signedBy "chris";

与以前一样,HighScorePermission 本身需要由实际实现权限的"chris"签名。

将所有内容整合在一起

原文:docs.oracle.com/javase/tutorial/security/userperm/together.html

在这里,我们模拟依次成为HighScore开发者(克里斯),ExampleGame开发者(特里),以及运行游戏的用户(金)。

您可以执行所有指定的步骤,然后(作为金的最后一步)运行ExampleGame

这些步骤没有解释。关于代码签名者(如克里斯和特里)和接收此类代码的人(如金)需要采取的进一步信息,请参阅签署代码并授予权限课程。

这里是步骤:

  • HighScore 开发者(克里斯)的步骤
  • ExampleGame 开发者(特里)的步骤
  • 运行 ExampleGame 的用户(金)的步骤

高分开发者(克里斯)的步骤

原文:docs.oracle.com/javase/tutorial/security/userperm/chris.html

克里斯在创建HighScoreHighScorePermission类之后将采取的步骤是:

编译这些类

javac HighScore*.java -d .

将类文件放入一个 JAR 文件中

jar cvf hs.jar com/scoredev/scores/HighScore*.class

创建用于签名的密钥库和密钥

keytool -genkey -keystore chris.keystore -alias signJars

指定密码和显著名称信息

签署 JAR 文件

jarsigner -keystore chris.keystore hs.jar signJars

导出公钥证书

keytool -export -keystore chris.keystore
    -alias signJars -file Chris.cer

提供游戏开发人员和用户所需的文件和信息

也就是说,提供它们

  • 签名的 JAR 文件hs.jar
  • 公钥证书文件Chris.cer
  • HighScoreHighScorePermission类在策略文件中必须被授予的权限信息,以便能够正常工作。对于这一点,克里斯可以提供所需的确切授权条目。

示例游戏开发者(Terry)的步骤

原文:docs.oracle.com/javase/tutorial/security/userperm/terry.html

Terry 创建一个调用 HighScoregetHighScoresetHighScore 方法来获取和设置用户高分的游戏(ExampleGame)后,Terry 需要采取的步骤是:

编译游戏类

javac ExampleGame.java -classpath hs.jar -d .

将其类文件放入一个 JAR 文件中

jar cvf terry.jar com/gamedev/games/ExampleGame.class

创建用于签名的密钥库和密钥

keytool -genkey -keystore terry.keystore -alias signTJars

为密码和区分名称信息指定任何你想要的内容。

签署 JAR 文件

jarsigner -keystore terry.keystore terry.jar signTJars

导出公钥证书

keytool -export -keystore terry.keystore
    -alias signTJars -file Terry.cer

为用户提供所需的文件和信息

也就是说,向他们提供

  • 签名的 JAR 文件 terry.jar,
  • 公钥证书文件 Terry.cer, 和
  • ExampleGame 类所需权限的信息。对于这一点,Terry 可能会提供所需的确切授权条目。

游戏用户还需要来自 Chris 的文件和信息。为了方便他们,Terry 可能会将这些信息转发给他们:

  • 签名的 JAR 文件 hs.jar,
  • 公钥证书文件 Chris.cer, 和
  • 有关 HighScoreHighScorePermission 类在策略文件中必须被授予的权限的信息,以便其正常工作。这可能是所需的确切授权条目。

运行 ExampleGame(Kim)的用户步骤

原文:docs.oracle.com/javase/tutorial/security/userperm/kim.html

用户(比如 Kim)需要执行的步骤包括:

将证书导入为受信任的证书

keytool -import -alias chris -file Chris.cer -keystore kim.keystore
keytool -import -alias terry -file Terry.cer -keystore kim.keystore

设置具有所需权限的策略文件

这里是完整的kim.policy策略文件,如 A Sample Policy File 中所述。

运行 ExampleGame

设置高分:

java -Djava.security.manager 
    -Djava.security.policy=kim.policy
    -classpath hs.jar;terry.jar
    com.gamedev.games.ExampleGame set 456

获取高分:

java -Djava.security.manager
    -Djava.security.policy=kim.policy
    -classpath hs.jar;terry.jar
    com.gamedev.games.ExampleGame get

注意:

  • 如果不指定-Djava.security.manager,应用程序将无限制地运行(策略文件和权限不会被检查)。
  • -Djava.security.policy=kim.policy指定了策略文件的位置。注意:还有其他指定策略文件的方法。例如,你可以在安全属性文件中添加一个条目,指定包含kim.policy,如在查看策略文件效果课程末尾讨论的那样。
  • -classpath hs.jar;terry.jar指定了包含所需类文件的 JAR 文件。对于 Windows,使用分号(“;”)分隔 JAR 文件;对于 UNIX,使用冒号(“:”)。
  • 策略文件kim.policy指定了密钥库kim.keystore。由于未提供密钥库的绝对 URL 位置,因此假定密钥库与策略文件位于同一目录中。

教程:扩展机制

原文:docs.oracle.com/javase/tutorial/ext/index.html

扩展机制提供了一种标准、可扩展的方式,使自定义 API 对在 Java 平台上运行的所有应用程序可用。Java 扩展也被称为可选包。本教程可能会交替使用这两个术语。

扩展是通过扩展机制增强 Java 平台的一组包和类。扩展机制使运行时环境能够找到并加载扩展类,而无需在类路径上命名扩展类。在这方面,扩展类类似于 Java 平台的核心类。这也是扩展得名的原因–它们实际上扩展了平台的核心 API。

由于此机制扩展了平台的核心 API,应谨慎使用。最常见的用途是用于由 Java 社区流程定义的标准化接口,尽管也可能适用于站点范围接口。


如图所示,扩展充当 Java 平台的“附加”模块。它们的类和公共 API 自动对在平台上运行的任何应用程序可用。

扩展机制还提供了一种从远程位置下载扩展类供 applets 使用的方法。

扩展被打包为 Java 存档(JAR)文件,本教程假定您熟悉 JAR 文件格式。如果您对 JAR 文件不熟悉,您可能需要在继续本教程的课程之前查阅一些 JAR 文件文档:

  • 本教程中的在 JAR 文件中打包程序课程。
  • JDK™文档中的JAR 指南

本教程有两个课程:

创建和使用扩展

这一部分向您展示了如何向您的 Java 平台添加扩展,并且 applets 如何通过下载远程扩展类从扩展机制中受益。

使扩展安全

本节描述了在您的平台上授予扩展的安全特权和权限。如果您正在编写自己的扩展类,您将了解如何使用 Java 平台的安全架构。

附加文档

您可以在 JDK 文档的Java 扩展机制部分找到有关扩展的更多信息。

教程:创建和使用扩展

原文:docs.oracle.com/javase/tutorial/ext/basics/index.html

任何一组包或类都可以轻松地扮演扩展的角色。将一组类转变为扩展的第一步是将它们打包在一个 JAR 文件中。完成这一步后,您可以通过两种方式将软件转变为扩展:

  • 通过将 JAR 文件放置在 Java 运行时环境目录结构的特定位置,这种情况下称为已安装扩展。
  • 通过以特定方式从另一个 JAR 文件的清单中引用 JAR 文件,这种情况下称为下载扩展。

本课将通过使用一个简单的“玩具”扩展作为示例来展示扩展机制的工作原理。

已安装扩展

在本节中,您将创建一个简单的已安装扩展,并看到扩展软件如何被运行时环境视为平台的一部分。

下载扩展

本节将向您展示如何修改 JAR 文件的清单,以便 JAR 打包的软件可以利用下载扩展。

理解扩展类加载

本节是一个简短的插曲,总结了 Java 平台的类加载委托模型,并展示了它与扩展中类加载的关系。

创建可扩展应用程序

本节讨论了用于扩展应用程序的机制,通过插件或模块,而无需修改其原始代码库。

下一课,使扩展安全 使用相同的扩展来展示 Java 平台如何控制授予扩展的安全权限。

已安装的扩展

原文:docs.oracle.com/javase/tutorial/ext/basics/install.html

已安装的扩展是 JRE™软件的lib/ext目录中的 JAR 文件。顾名思义,JRE 是 Java 开发工具包的运行时部分,包含平台的核心 API,但不包括编译器和调试器等开发工具。JRE 可以单独使用,也可以作为 Java 开发工具包的一部分使用。

JRE 是 JDK 软件的严格子集。JDK 软件目录树的子集如下所示:


JRE 由图中突出显示的目录组成。无论您的 JRE 是独立的还是作为 JDK 软件的一部分,JRE 目录中的lib/ext中的任何 JAR 文件都会被运行时环境自动视为扩展。

由于安装的扩展会扩展平台的核心 API,请谨慎使用。它们很少适用于仅由单个或少量应用程序使用的接口。

此外,由于安装的扩展定义的符号将在所有 Java 进程中可见,因此应注意确保所有可见符号遵循适当的“反向域名”和“类层次结构”约定。例如,com.mycompany.MyClass

从 Java 6 开始,扩展 JAR 文件也可以放置在与任何特定 JRE 无关的位置,以便扩展可以被安装在系统上安装的所有 JRE 共享。在 Java 6 之前,java.ext.dirs的值指的是单个目录,但是从 Java 6 开始,它是一个目录列表(类似于CLASSPATH),指定扩展被搜索的位置。路径的第一个元素始终是 JRE 的lib/ext目录。第二个元素是 JRE 之外的目录。这个其他位置允许扩展 JAR 文件只安装一次,并被安装在该系统上安装的几个 JRE 使用。位置因操作系统而异:

  • Solaris™操作系统: /usr/jdk/packages/lib/ext
  • Linux: /usr/java/packages/lib/ext
  • Microsoft Windows: %SystemRoot%\Sun\Java\lib\ext

请注意,放置在上述任一目录中的安装扩展会扩展该系统上每个JRE(Java 6 或更高版本)的平台。

一个简单的例子

让我们创建一个简单的已安装扩展。我们的扩展由一个类RectangleArea组成,用于计算矩形的面积:

public final class RectangleArea {
    public static int area(java.awt.Rectangle r) {
        return r.width * r.height;
    }
}

此类有一个名为area的方法,该方法接受一个java.awt.Rectangle的实例并返回矩形的面积。

假设你想要使用名为AreaApp的应用程序测试RectangleArea

import java.awt.*;
public class AreaApp {
    public static void main(String[] args) {
        int width = 10;
        int height = 5;
        Rectangle r = new Rectangle(width, height);
        System.out.println("The rectangle's area is " 
                           + RectangleArea.area(r));
    }
}

此应用程序实例化一个 10 x 5 的矩形,然后使用RectangleArea.area方法打印出矩形的面积。

在没有扩展机制的情况下运行 AreaApp

让我们首先回顾一下如何在不使用扩展机制的情况下运行AreaApp应用程序。我们假设RectangleArea类被捆绑在名为area.jar的 JAR 文件中。

当然,RectangleArea类不是 Java 平台的一部分,因此您需要将area.jar文件放在类路径上才能运行AreaApp而不会出现运行时异常。例如,如果area.jar在目录/home/user中,您可以使用以下命令:

java -classpath .:/home/user/area.jar AreaApp 

此命令中指定的类路径包含当前目录,其中包含AreaApp.class,以及包含RectangleArea包的 JAR 文件的路径。通过运行此命令,您将获得所需的输出:

The rectangle's area is 50

使用扩展机制运行 AreaApp

现在让我们看看如何通过将RectangleArea类作为扩展来运行AreaApp

要将RectangleArea类变成一个扩展,您需要将文件area.jar放在 JRE 的lib/ext目录中。这样做会自动将RectangleArea赋予已安装扩展的状态。

area.jar安装为扩展后,您可以运行AreaApp而无需指定类路径:

java AreaApp 

因为您正在使用area.jar作为已安装的扩展,运行时环境将能够找到并加载RectangleArea类,即使您没有在类路径上指定它。同样,任何用户在您的系统上运行的小程序或应用程序都可以找到并使用RectangleArea类。

如果系统上安装了多个 JRE(Java 6 或更高版本),并且希望RectangleArea类作为所有 JRE 的扩展可用,而不是将其安装在特定 JRE 的lib/ext目录中,请将其安装在系统范围的位置。例如,在运行 Linux 的系统上,将area.jar安装在目录/usr/java/packages/lib/ext中。然后AreaApp可以在安装在该系统上的不同 JRE 上运行,例如,如果不同的浏览器配置为使用不同的 JRE。

下载扩展

原文:docs.oracle.com/javase/tutorial/ext/basics/download.html

下载扩展是 JAR 文件中的一组类(和相关资源)。JAR 文件的清单可以包含引用一个或多个下载扩展的头部。这些扩展可以通过以下两种方式引用:

  • 通过Class-Path头部
  • 通过Extension-List头部

请注意,清单中最多只允许一个。通过Class-Path头部指示的下载扩展仅在下载它们的应用程序(如 Web 浏览器)的生命周期内下载。它们的优点是客户端上没有安装任何内容;缺点是每次需要时都会下载它们。通过Extension-List头部下载的下载扩展将安装到下载它们的 JRE 的/lib/ext目录中。它们的优点是第一次需要时下载,随后可以在不下载的情况下使用。但是,正如本教程后面所示,它们部署起来更加复杂。

由于使用Class-Path头部的下载扩展更简单,让我们先考虑它们。例如假设a.jarb.jar是同一目录中的两个 JAR 文件,并且a.jar的清单包含了这个头部:

Class-Path: b.jar

那么b.jar中的类将作为a.jar中的类的扩展类。a.jar中的类可以调用b.jar中的类,而无需将b.jar中的类命名在类路径中。a.jar本身可能是扩展,也可能不是。如果b.jar不在与a.jar相同的目录中,那么Class-Path头部的值应设置为b.jar的相对路径名。

扮演下载扩展角色的类没有任何特殊之处。它们之所以被视为扩展,仅仅是因为它们被某个其他 JAR 文件的清单引用。

为了更好地理解下载扩展的工作原理,让我们创建一个并投入使用。

一个示例

假设你想要创建一个小程序,其中使用了前一节中的RectangleArea类:

public final class RectangleArea {  
    public static int area(java.awt.Rectangle r) {
        return r.width * r.height;
    }
}

在前一节中,你将RectangleArea类放入 JRE 的lib/ext目录中,将其转换为已安装扩展。通过将其转换为已安装扩展,任何应用程序都可以使用RectangleArea类,就好像它是 Java 平台的一部分。

如果你想要在小程序中使用RectangleArea类,情况会有些不同。例如,假设你有一个名为AreaApplet的小程序,其中使用了RectangleArea类:

import java.applet.Applet;
import java.awt.*;
public class AreaApplet extends Applet {
    Rectangle r;
    public void init() {    
        int width = 10;
        int height = 5;
        r = new Rectangle(width, height);
    }
    public void paint(Graphics g) {
        g.drawString("The rectangle's area is " 
                      + RectangleArea.area(r), 10, 10);
    }
}

此小程序实例化一个 10 x 5 的矩形,然后使用RectangleArea.area方法显示矩形的面积。

然而,你不能假设每个下载并使用你的小程序的人都会在他们的系统上有RectangleArea类可用,作为已安装的扩展或其他方式。解决这个问题的一种方法是从服务器端提供RectangleArea类,并且你可以通过将其作为下载扩展来实现。

要了解如何做到这一点,让我们假设你已经将AreaApplet捆绑在名为AreaApplet.jar的 JAR 文件中,并且类RectangleArea捆绑在RectangleArea.jar中。为了使RectangleArea.jar被视为下载扩展,RectangleArea.jar必须在AreaApplet.jar的清单中的Class-Path头中列出。例如,AreaApplet.jar的清单可能如下所示:

Manifest-Version: 1.0
Class-Path: RectangleArea.jar

这个清单中Class-Path头的值是RectangleArea.jar,没有指定路径,表示RectangleArea.jar位于与小程序的 JAR 文件相同的目录中。

关于Class-Path头的更多信息

如果一个小程序或应用程序使用多个扩展,你可以在清单中列出多个 URL。例如,以下是一个有效的头部:

Class-Path: area.jar servlet.jar images/

Class-Path头中,列出的任何不以’/‘结尾的 URL 都被假定为 JAR 文件。以’/'结尾的 URL 表示目录。在上面的例子中,images/可能是一个包含小程序或应用程序所需资源的目录。

请注意,清单文件中只允许一个Class-Path头,并且清单中的每一行不能超过 72 个字符。如果需要指定的类路径条目超过一行的空间,可以将它们延伸到后续的续行上。每个续行都以两个空格开头。例如:

Class-Path: area.jar servlet.jar monitor.jar datasource.jar
  provider.jar gui.jar

未来的版本可能会取消每个标题只能有一个实例的限制,以及将行限制为仅有 72 个字符。

下载扩展可以“串联”,意味着一个下载扩展的清单可以有一个引用第二个扩展的Class-Path头,第二个扩展可以引用第三个扩展,依此类推。

安装下载扩展

在上面的例子中,小程序下载的扩展仅在加载小程序的浏览器仍在运行时可用。然而,如果在小程序和扩展的清单中包含了额外的信息,小程序可以触发扩展的安装。

由于这种机制扩展了平台的核心 API,其使用应谨慎。它很少适用于仅由单个或少量应用程序使用的接口。所有可见的符号应遵循反向域名和类层次结构约定。

基本要求是小程序和它使用的扩展在它们的清单中提供版本信息,并且它们被签名。版本信息允许 Java 插件确保扩展代码具有小程序期望的版本。例如,AreaApplet可以在其清单中指定一个areatest扩展:

Manifest-Version: 1.0
Extension-List: areatest
areatest-Extension-Name: area
areatest-Specification-Version: 1.1
areatest-Implementation-Version: 1.1.2
areatest-Implementation-Vendor-Id: com.example
areatest-Implementation-URL: http://www.example.com/test/area.jar

area.jar中的清单将提供相应的信息:

Manifest-Version: 1.0
Extension-Name: area
Specification-Vendor: Example Tech, Inc
Specification-Version: 1.1
Implementation-Vendor-Id: com.example
Implementation-Vendor: Example Tech, Inc
Implementation-Version: 1.1.2

应用程序和扩展程序都必须由相同的签名者签名。对 jar 文件进行签名会直接修改它们,在清单文件中提供更多信息。签名有助于确保只有可信任的代码被安装。签署 jar 文件的简单方法是首先创建一个密钥库,然后使用该密钥库保存用于应用程序和扩展程序的证书。例如:

keytool -genkey -dname "cn=Fred" -alias test  -validity 180

您将被要求输入密钥库和密钥密码。生成密钥后,jar 文件可以被签名:

jarsigner AreaApplet.jar test
jarsigner area.jar test

您将被要求输入密钥库和密钥密码。有关keytooljarsigner和其他安全工具的更多信息,请参阅Java 2 平台安全工具概述

这里是AreaDemo.html,它加载应用程序并导致扩展程序代码被下载并安装:

<html>
<body>
  <applet code="AreaApplet.class" archive="AreaApplet.jar"/>
</body>
</html>

当页面首次加载时,用户会被告知该应用程序需要安装扩展程序。随后的对话框会通知用户有关已签名的应用程序。接受两者会将扩展程序安装在 JRE 的lib/ext文件夹中并运行应用程序。

重新启动 Web 浏览器并加载相同的网页后,只会显示有关应用程序签名者的对话框,因为area.jar已经安装。如果在不同的 Web 浏览器中打开AreaDemo.html(假设两个浏览器都使用相同的 JRE),情况也是如此。

理解扩展类加载

译文:docs.oracle.com/javase/tutorial/ext/basics/load.html

扩展框架利用了类加载委托机制。当运行时环境需要为应用程序加载新类时,它按照以下顺序在以下位置查找类:

  1. 引导类rt.jar中的运行时类,i18n.jar中的国际化类等。
  2. 已安装扩展:JRE 的lib/ext目录中的 JAR 文件中的类,以及系统范围内的特定于平台的扩展目录(例如在 Solaris™操作系统上的/usr/jdk/packages/lib/ext,但请注意,此目录仅适用于 Java™ 6 及更高版本)。
  3. 类路径:包括系统属性java.class.path指定路径上的类,包括 JAR 文件中的类。如果类路径上的 JAR 文件具有带有Class-Path属性的清单,则还将搜索Class-Path属性指定的 JAR 文件。默认情况下,java.class.path属性的值为.,即当前目录。您可以通过使用-classpath-cp命令行选项或设置CLASSPATH环境变量来更改该值。命令行选项会覆盖CLASSPATH环境变量的设置。

优先级列表告诉您,例如,只有在要加载的类在rt.jari18n.jar或已安装扩展中的类中未找到时,才会搜索类路径。

除非您的软件为特殊目的实例化自己的类加载器,否则您实际上不需要了解比记住这个优先级列表更多的内容。特别是,您应该注意可能存在的任何类名冲突。例如,如果您在类路径上列出一个类,如果运行时环境代替加载了安装的扩展中找到的同名另一个类,您将得到意外的结果。

Java 类加载机制

Java 平台使用委托模型来加载类。基本思想是每个类加载器都有一个“父”类加载器。在加载类时,类加载器首先将类的搜索委托给其父类加载器,然后再尝试找到类本身。

以下是类加载 API 的一些亮点:

  • java.lang.ClassLoader及其子类中的构造函数允许您在实例化新类加载器时指定一个父类加载器。如果您没有明确指定父类加载器,则虚拟机的系统类加载器将被分配为默认父类加载器。
  • 当调用ClassLoader中的loadClass方法加载类时,它按顺序执行以下任务:
  1. 如果类已经被加载,它会返回该类。
  2. 否则,它将搜索新类的任务委托给父类加载器。
  3. 如果父类加载器未找到类,loadClass调用findClass方法来查找和加载类。
  • 如果父类加载器未找到类,则ClassLoaderfindClass方法将在当前类加载器中搜索该类。当您在应用程序中实例化类加载器子类时,可能需要重写此方法。
  • java.net.URLClassLoader用作扩展和其他 JAR 文件的基本类加载器,覆盖了java.lang.ClassLoaderfindClass方法,以在一个或多个指定的 URL 中搜索类和资源。

要查看一个使用与 JAR 文件相关的 API 的示例应用程序,请参阅本教程中的使用与 JAR 相关的 API 课程。

类加载和java命令

Java 平台的类加载机制体现在java命令中。

  • java工具中,-classpath选项是设置java.class.path属性的简便方式。
  • -cp-classpath选项是等效的。
  • -jar选项用于运行打包在 JAR 文件中的应用程序。有关此选项的描述和示例,请参阅本教程中的运行 JAR 打包软件课程。

创建可扩展应用程序

原文:docs.oracle.com/javase/tutorial/ext/basics/spi.html

下面涵盖了以下主题:

  • 介绍
  • 字典服务示例
  • 运行 DictionaryServiceDemo 示例
  • 编译和运行 DictionaryServiceDemo 示例
  • 理解 DictionaryServiceDemo 示例
  1. 定义服务提供者接口
  2. 定义检索服务提供者实现的服务
  • 单例设计模式
  1. 实现服务提供者
  2. 注册服务提供者
  3. 创建使用服务和服务提供者的客户端
  4. 将服务提供者、服务和服务客户端打包在 JAR 文件中
  • 将服务提供者打包在 JAR 文件中
  • 将字典 SPI 和字典服务打包在 JAR 文件中
  • 将客户端打包在 JAR 文件中
  1. 运行客户端
  • ServiceLoader 类
  • ServiceLoader API 的限制
  • 摘要

Java 中文官方教程 2022 版(四十二)(4)https://developer.aliyun.com/article/1488235

相关文章
|
7月前
|
JavaScript NoSQL Java
接替此文【下篇-服务端+后台管理】优雅草蜻蜓z系统JAVA版暗影版为例-【蜻蜓z系列通用】-2025年全新项目整合搭建方式-这是独立吃透代码以后首次改变-独立PC版本vue版搭建教程-优雅草卓伊凡
接替此文【下篇-服务端+后台管理】优雅草蜻蜓z系统JAVA版暗影版为例-【蜻蜓z系列通用】-2025年全新项目整合搭建方式-这是独立吃透代码以后首次改变-独立PC版本vue版搭建教程-优雅草卓伊凡
361 96
接替此文【下篇-服务端+后台管理】优雅草蜻蜓z系统JAVA版暗影版为例-【蜻蜓z系列通用】-2025年全新项目整合搭建方式-这是独立吃透代码以后首次改变-独立PC版本vue版搭建教程-优雅草卓伊凡
|
3月前
|
Oracle Java 关系型数据库
java 编程基础入门级超级完整版教程详解
这份文档是针对Java编程入门学习者的超级完整版教程,涵盖了从环境搭建到实际项目应用的全方位内容。首先介绍了Java的基本概念与开发环境配置方法,随后深入讲解了基础语法、控制流程、面向对象编程的核心思想,并配以具体代码示例。接着探讨了常用类库与API的应用,如字符串操作、集合框架及文件处理等。最后通过一个学生成绩管理系统的实例,帮助读者将理论知识应用于实践。此外,还提供了进阶学习建议,引导学员逐步掌握更复杂的Java技术。适合初学者系统性学习Java编程。资源地址:[点击访问](https://pan.quark.cn/s/14fcf913bae6)。
305 2
|
8月前
|
消息中间件 Java 数据库
自研Java框架 Sunrays-Framework使用教程「博客之星」
### Sunrays-Framework:助力高效开发的Java微服务框架 **Sunrays-Framework** 是一款基于 Spring Boot 构建的高效微服务开发框架,深度融合了 Spring Cloud 生态中的核心技术组件。它旨在简化数据访问、缓存管理、消息队列、文件存储等常见开发任务,帮助开发者快速构建高质量的企业级应用。 #### 核心功能 - **MyBatis-Plus**:简化数据访问层开发,提供强大的 CRUD 操作和分页功能。 - **Redis**:实现高性能缓存和分布式锁,提升系统响应速度。 - **RabbitMQ**:可靠的消息队列支持,适用于异步
自研Java框架 Sunrays-Framework使用教程「博客之星」
|
9月前
|
移动开发 前端开发 Java
Java最新图形化界面开发技术——JavaFx教程(含UI控件用法介绍、属性绑定、事件监听、FXML)
JavaFX是Java的下一代图形用户界面工具包。JavaFX是一组图形和媒体API,我们可以用它们来创建和部署富客户端应用程序。 JavaFX允许开发人员快速构建丰富的跨平台应用程序,允许开发人员在单个编程接口中组合图形,动画和UI控件。本文详细介绍了JavaFx的常见用法,相信读完本教程你一定有所收获!
8410 5
Java最新图形化界面开发技术——JavaFx教程(含UI控件用法介绍、属性绑定、事件监听、FXML)
|
8月前
|
Java 数据库连接 数据处理
探究Java异常处理【保姆级教程】
Java 异常处理是确保程序稳健运行的关键机制。它通过捕获和处理运行时错误,避免程序崩溃。Java 的异常体系以 `Throwable` 为基础,分为 `Error` 和 `Exception`。前者表示严重错误,后者可细分为受检和非受检异常。常见的异常处理方式包括 `try-catch-finally`、`throws` 和 `throw` 关键字。此外,还可以自定义异常类以满足特定需求。最佳实践包括捕获具体异常、合理使用 `finally` 块和谨慎抛出异常。掌握这些技巧能显著提升程序的健壮性和可靠性。
133 4
|
8月前
|
存储 移动开发 算法
【潜意识Java】Java基础教程:从零开始的学习之旅
本文介绍了 Java 编程语言的基础知识,涵盖从简介、程序结构到面向对象编程的核心概念。首先,Java 是一种高级、跨平台的面向对象语言,支持“一次编写,到处运行”。接着,文章详细讲解了 Java 程序的基本结构,包括包声明、导入语句、类声明和 main 方法。随后,深入探讨了基础语法,如数据类型、变量、控制结构、方法和数组。此外,还介绍了面向对象编程的关键概念,例如类与对象、继承和多态。最后,针对常见的编程错误提供了调试技巧,并总结了学习 Java 的重要性和方法。适合初学者逐步掌握 Java 编程。
145 1
|
9月前
|
NoSQL Java 关系型数据库
Liunx部署java项目Tomcat、Redis、Mysql教程
本文详细介绍了如何在 Linux 服务器上安装和配置 Tomcat、MySQL 和 Redis,并部署 Java 项目。通过这些步骤,您可以搭建一个高效稳定的 Java 应用运行环境。希望本文能为您在实际操作中提供有价值的参考。
556 26
|
8月前
|
前端开发 Java 开发工具
Git使用教程-将idea本地Java等文件配置到gitte上【保姆级教程】
本内容详细介绍了使用Git进行版本控制的全过程,涵盖从本地仓库创建到远程仓库配置,以及最终推送代码至远程仓库的步骤。
415 0
|
9月前
|
安全 Java 编译器
Kotlin教程笔记(27) -Kotlin 与 Java 共存(二)
Kotlin教程笔记(27) -Kotlin 与 Java 共存(二)
|
9月前
|
Java 开发工具 Android开发
Kotlin教程笔记(26) -Kotlin 与 Java 共存(一)
Kotlin教程笔记(26) -Kotlin 与 Java 共存(一)

热门文章

最新文章