`

java之classloader体系结构(含hotswap)

    博客分类:
  • j2se
阅读更多

jvm classLoader architecture :

a, Bootstrap ClassLoader/启动类加载器
主要负责jdk_home/lib目录下的核心 api 或 -Xbootclasspath 选项指定的jar包装入工作.

 

b, Extension ClassLoader/扩展类加载器
主要负责jdk_home/lib/ext目录下的jar包或 -Djava.ext.dirs 指定目录下的jar包装入工作

 

c, System ClassLoader/系统类加载器
主要负责java -classpath/-Djava.class.path所指的目录下的类与jar包装入工作.

 

b, User Custom ClassLoader/用户自定义类加载器(java.lang.ClassLoader的子类)
在程序运行期间, 通过java.lang.ClassLoader的子类动态加载class文件, 体现java动态实时类装入特性.

 

类加载器的特性:

1, 每个ClassLoader都维护了一份自己的名称空间, 同一个名称空间里不能出现两个同名的类。
2, 为了实现java安全沙箱模型顶层的类加载器安全机制, java默认采用了 ” 双亲委派的加载链 ” 结构.


如下图:
java class loader

Class Diagram:
classloader 类图

类图中, BootstrapClassLoader是一个单独的java类, 其实在这里, 不应该叫他是一个java类。
因为, 它已经完全不用java实现了。

 

它是在jvm启动时, 就被构造起来的, 负责java平台核心库。(具体上面已经有介绍)

启动类加载实现 (其实我们不用关心这块, 但是有兴趣的, 可以研究一下 ):
bootstrap classLoader 类加载原理探索

 

自定义类加载器加载一个类的步骤 :

自定义类加载器加载一个类的步骤

 

ClassLoader 类加载逻辑分析, 以下逻辑是除 BootstrapClassLoader 外的类加载器加载流程:

 

Java代码 复制代码
  1. // 检查类是否已被装载过   
  2. Class c = findLoadedClass(name);   
  3. if (c == null ) {   
  4.      // 指定类未被装载过   
  5.      try {   
  6.          if (parent != null ) {   
  7.              // 如果父类加载器不为空, 则委派给父类加载   
  8.              c = parent.loadClass(name, false );   
  9.          } else {   
  10.              // 如果父类加载器为空, 则委派给启动类加载加载   
  11.              c = findBootstrapClass0(name);   
  12.          }   
  13.      } catch (ClassNotFoundException e) {   
  14.          // 启动类加载器或父类加载器抛出异常后, 当前类加载器将其   
  15.          // 捕获, 并通过findClass方法, 由自身加载   
  16.          c = findClass(name);   
  17.      }   
  18. }  
// 检查类是否已被装载过
Class c = findLoadedClass(name);
if (c == null ) {
     // 指定类未被装载过
     try {
         if (parent != null ) {
             // 如果父类加载器不为空, 则委派给父类加载
             c = parent.loadClass(name, false );
         } else {
             // 如果父类加载器为空, 则委派给启动类加载加载
             c = findBootstrapClass0(name);
         }
     } catch (ClassNotFoundException e) {
         // 启动类加载器或父类加载器抛出异常后, 当前类加载器将其
         // 捕获, 并通过findClass方法, 由自身加载
         c = findClass(name);
     }
}

 

用Class.forName加载类
Class.forName使用的是被调用者的类加载器来加载类的.
这种特性, 证明了java类加载器中的名称空间是唯一的, 不会相互干扰.

即在一般情况下, 保证同一个类中所关联的其他类都是由当前类的类加载器所加载的.

 

Java代码 复制代码
  1. public static Class forName(String className)   
  2.      throws ClassNotFoundException {   
  3.      return forName0(className, true , ClassLoader.getCallerClassLoader());   
  4. }   
  5.     
  6. /** Called after security checks have been made. */  
  7. private static native Class forName0(String name, boolean initialize,   
  8. ClassLoader loader)   
  9.      throws ClassNotFoundException;  
public static Class forName(String className)
     throws ClassNotFoundException {
     return forName0(className, true , ClassLoader.getCallerClassLoader());
}
 
/** Called after security checks have been made. */
private static native Class forName0(String name, boolean initialize,
ClassLoader loader)
     throws ClassNotFoundException;

 

上图中 ClassLoader.getCallerClassLoader 就是得到调用当前forName方法的类的类加载器

 

线程上下文类加载器
java默认的线程上下文类加载器是 系统类加载器(AppClassLoader).

 

Java代码 复制代码
  1. // Now create the class loader to use to launch the application   
  2. try {   
  3.     loader = AppClassLoader.getAppClassLoader(extcl);   
  4. catch (IOException e) {   
  5.     throw new InternalError(   
  6. "Could not create application class loader" );   
  7. }   
  8.     
  9. // Also set the context class loader for the primordial thread.   
  10. Thread.currentThread().setContextClassLoader(loader);  
// Now create the class loader to use to launch the application
try {
    loader = AppClassLoader.getAppClassLoader(extcl);
} catch (IOException e) {
    throw new InternalError(
"Could not create application class loader" );
}
 
// Also set the context class loader for the primordial thread.
Thread.currentThread().setContextClassLoader(loader);

 

以上代码摘自sun.misc.Launch的无参构造函数Launch()。

使用线程上下文类加载器, 可以在执行线程中, 抛弃双亲委派加载链模式, 使用线程上下文里的类加载器加载类.
典型的例子有, 通过线程上下文来加载第三方库jndi实现, 而不依赖于双亲委派.

大部分java app服务器(jboss, tomcat..)也是采用contextClassLoader来处理web服务。
还有一些采用 hotswap 特性的框架, 也使用了线程上下文类加载器, 比如 seasar (full stack framework in japenese).

线程上下文从根本解决了一般应用不能违背双亲委派模式的问题.

使java类加载体系显得更灵活.

 

随着多核时代的来临, 相信多线程开发将会越来越多地进入程序员的实际编码过程中. 因此,
在编写基础设施时, 通过使用线程上下文来加载类, 应该是一个很好的选择.

 

当然, 好东西都有利弊. 使用线程上下文加载类, 也要注意, 保证多根需要通信的线程间的类加载器应该是同一个,
防止因为不同的类加载器, 导致类型转换异常(ClassCastException).

 

自定义的类加载器实现
defineClass(String name, byte[] b, int off, int len,ProtectionDomain protectionDomain)
是java.lang.Classloader提供给开发人员, 用来自定义加载class的接口.

使用该接口, 可以动态的加载class文件.

 

例如,
在jdk中, URLClassLoader是配合findClass方法来使用defineClass, 可以从网络或硬盘上加载class.

而使用类加载接口, 并加上自己的实现逻辑, 还可以定制出更多的高级特性.

 

比如,

一个简单的hot swap 类加载器实现:

 

 

Java代码 复制代码
  1. import java.io.File;   
  2. import java.io.FileInputStream;   
  3. import java.lang.reflect.Method;   
  4. import java.net.URL;   
  5. import java.net.URLClassLoader;   
  6.     
  7. /**  
  8. * 可以重新载入同名类的类加载器实现  
  9. *  
  10.    
  11. * 放弃了双亲委派的加载链模式.  
  12. * 需要外部维护重载后的类的成员变量状态.  
  13. *  
  14. * @author ken.wu  
  15. * @mail ken.wug@gmail.com  
  16. * 2007-9-28 下午01:37:43  
  17. */  
  18. public class HotSwapClassLoader extends URLClassLoader {   
  19.     
  20.     public HotSwapClassLoader(URL[] urls) {   
  21.         super (urls);   
  22.     }   
  23.     
  24.     public HotSwapClassLoader(URL[] urls, ClassLoader parent) {   
  25.         super (urls, parent);   
  26.     }   
  27.     
  28.     public Class load(String name)   
  29.           throws ClassNotFoundException {   
  30.         return load(name, false );   
  31.     }   
  32.     
  33.     public Class load(String name, boolean resolve)   
  34.           throws ClassNotFoundException {   
  35.         if ( null != super .findLoadedClass(name))   
  36.             return reload(name, resolve);   
  37.     
  38.         Class clazz = super .findClass(name);   
  39.     
  40.         if (resolve)   
  41.             super .resolveClass(clazz);   
  42.     
  43.         return clazz;   
  44.     }   
  45.     
  46.     public Class reload(String name, boolean resolve)   
  47.           throws ClassNotFoundException {   
  48.         return new HotSwapClassLoader( super .getURLs(), super .getParent()).load(   
  49.             name, resolve);   
  50.     }   
  51. }   
  52.     
  53. public class A {   
  54.     private B b;   
  55.     
  56.     public void setB(B b) {   
  57.          this .b = b;   
  58.     }   
  59.     
  60.     public B getB() {   
  61.          return b;   
  62.     }   
  63. }   
  64.     
  65. public class B {}  
import java.io.File;
import java.io.FileInputStream;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
 
/**
* 可以重新载入同名类的类加载器实现
*
 
* 放弃了双亲委派的加载链模式.
* 需要外部维护重载后的类的成员变量状态.
*
* @author ken.wu
* @mail ken.wug@gmail.com
* 2007-9-28 下午01:37:43
*/
public class HotSwapClassLoader extends URLClassLoader {
 
    public HotSwapClassLoader(URL[] urls) {
        super (urls);
    }
 
    public HotSwapClassLoader(URL[] urls, ClassLoader parent) {
        super (urls, parent);
    }
 
    public Class load(String name)
          throws ClassNotFoundException {
        return load(name, false );
    }
 
    public Class load(String name, boolean resolve)
          throws ClassNotFoundException {
        if ( null != super .findLoadedClass(name))
            return reload(name, resolve);
 
        Class clazz = super .findClass(name);
 
        if (resolve)
            super .resolveClass(clazz);
 
        return clazz;
    }
 
    public Class reload(String name, boolean resolve)
          throws ClassNotFoundException {
        return new HotSwapClassLoader( super .getURLs(), super .getParent()).load(
            name, resolve);
    }
}
 
public class A {
    private B b;
 
    public void setB(B b) {
         this .b = b;
    }
 
    public B getB() {
         return b;
    }
}
 
public class B {}

 

 

这个类的作用是可以重新载入同名的类, 但是, 为了实现hotswap, 老的对象状态
需要通过其他方式拷贝到重载过的类生成的全新实例中来。(A类中的b实例)

而新实例所依赖的B类如果与老对象不是同一个类加载器加载的, 将会抛出类型转换异常(ClassCastException).

为了解决这种问题, HotSwapClassLoader自定义了load方法. 即当前类是由自身classLoader加载的, 而内部依赖的类

 

还是老对象的classLoader加载的.

 
Java代码 复制代码
  1. public class TestHotSwap {   
  2. public static void main(String args[]) {   
  3.     A a = new A();   
  4.     B b = new B();   
  5.     a.setB(b);   
  6.     
  7.     System.out.printf("A classLoader is %s n" , a.getClass().getClassLoader());   
  8.     System.out.printf("B classLoader is %s n" , b.getClass().getClassLoader());   
  9.     System.out.printf("A.b classLoader is %s n" ,   a.getB().getClass().getClassLoader());   
  10.     
  11.     HotSwapClassLoader c1 = new HotSwapClassLoader( new URL[]{ new URL( "file:\e:\test\")} , a.getClass().getClassLoader());   
  12.     Class clazz = c1.load(" test.hotswap.A ");   
  13.     Object aInstance = clazz.newInstance();   
  14.     
  15.     Method method1 = clazz.getMethod(" setB ", B.class);   
  16.     method1.invoke(aInstance, b);   
  17.     
  18.     Method method2 = clazz.getMethod(" getB "null);   
  19.     Object bInstance = method2.invoke(aInstance, null);   
  20.     
  21.     System.out.printf(" reloaded A.b classLoader is %s n", bInstance.getClass().getClassLoader());   
  22. }   
  23. }  
public class TestHotSwap {
public static void main(String args[]) {
    A a = new A();
    B b = new B();
    a.setB(b);
 
    System.out.printf("A classLoader is %s n" , a.getClass().getClassLoader());
    System.out.printf("B classLoader is %s n" , b.getClass().getClassLoader());
    System.out.printf("A.b classLoader is %s n" ,   a.getB().getClass().getClassLoader());
 
    HotSwapClassLoader c1 = new HotSwapClassLoader( new URL[]{ new URL( "file:\e:\test\")} , a.getClass().getClassLoader());
    Class clazz = c1.load(" test.hotswap.A ");
    Object aInstance = clazz.newInstance();
 
    Method method1 = clazz.getMethod(" setB ", B.class);
    method1.invoke(aInstance, b);
 
    Method method2 = clazz.getMethod(" getB ", null);
    Object bInstance = method2.invoke(aInstance, null);
 
    System.out.printf(" reloaded A.b classLoader is %s n", bInstance.getClass().getClassLoader());
}
}
 

 

输出

A classLoader is sun.misc.Launcher$AppClassLoader@19821f
B classLoader is sun.misc.Launcher$AppClassLoader@19821f
A.b classLoader is sun.misc.Launcher$AppClassLoader@19821f
reloaded A.b classLoader is sun.misc.Launcher$AppClassLoader@19821f

分享到:
评论

相关推荐

    classloader体系结构(含hotswap)

    Java的类加载器(ClassLoader)体系结构是JVM(Java虚拟机)中至关重要的一部分,它负责将类的字节码转换为运行时的类实例。本文将深入探讨启动类加载器、扩展类加载器、系统类加载器以及用户自定义类加载器,同时还...

    OFDM、OOK、PPM、QAM 的误码率模拟【绘制不同调制方案的误码率曲线】附Matlab代码.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。

    8c71b76fb2ec10cf50fc6b0308d3dcfc_9545878e2b97a84b2e089ece58da9e82.png

    8c71b76fb2ec10cf50fc6b0308d3dcfc_9545878e2b97a84b2e089ece58da9e82

    Android SO逆向-对象的拷贝构造函数.pdf

    Android逆向过程学习

    基于S7-200 PLC的糖果包装控制系统设计与实现

    内容概要:本文详细介绍了基于西门子S7-200 PLC的糖果包装控制系统的设计与实现。首先阐述了PLC在工业自动化领域的优势及其在糖果包装生产线中的重要性。接着深入探讨了系统的硬件连接方式,包括传感器、执行机构与PLC的具体接口配置。随后展示了关键的编程实现部分,如糖果计数、包装执行、送膜控制、称重判断以及热封温度控制等具体梯形图代码片段。此外,还分享了一些实用的经验技巧,如防止信号抖动、PID参数优化、故障诊断方法等。最后总结了该系统的优势,强调其对提高生产效率和产品质量的重要作用。 适合人群:从事工业自动化控制、PLC编程的技术人员,尤其是对小型PLC系统感兴趣的工程师。 使用场景及目标:适用于糖果制造企业,旨在提升包装生产线的自动化程度,确保高效稳定的生产过程,同时降低维护成本并提高产品一致性。 其他说明:文中不仅提供了详细的理论讲解和技术指导,还结合实际案例进行了经验分享,有助于读者更好地理解和掌握相关知识。

    PLC与WinCC实现三部十层电梯协同控制及优化技巧

    内容概要:本文详细介绍了参与西门子杯比赛中关于三部十层电梯系统的博图V15.1程序设计及其WinCC画面展示的内容。文中不仅展示了电梯系统的基本架构,如抢单逻辑、方向决策、状态机管理等核心算法(采用SCL语言编写),还分享了许多实际调试过程中遇到的问题及解决方案,例如未初始化变量导致的异常行为、状态机遗漏空闲状态、WinCC画面动态显示的挑战以及通信配置中的ASCII码解析错误等问题。此外,作者还特别提到一些创意性的设计,如电梯同时到达同一层时楼层显示器变为闪烁爱心的效果,以及节能模式下电梯自动停靠中间楼层的功能。 适合人群:对PLC编程、工业自动化控制、电梯调度算法感兴趣的工程技术人员,尤其是准备参加类似竞赛的学生和技术爱好者。 使用场景及目标:适用于希望深入了解PLC编程实践、掌握电梯群控系统的设计思路和技术要点的人士。通过学习本文可以更好地理解如何利用PLC进行复杂的机电一体化项目的开发,提高解决实际问题的能力。 其他说明:文章风格幽默诙谐,将严肃的技术话题融入轻松的生活化比喻之中,使得原本枯燥的专业知识变得生动有趣。同时,文中提供的经验教训对于从事相关领域的工作者来说非常宝贵,能够帮助他们少走弯路并激发更多创新思维。

    慧荣量产工具合集.zip

    慧荣量产工具合集.zip

    永磁同步电机FOC控制与SVPWM算法仿真模型解析

    内容概要:本文详细介绍了永磁同步电机(PMSM)的FOC(磁场定向控制)和SVPWM(空间矢量脉宽调制)算法的仿真模型。首先解释了FOC的基本原理及其核心的坐标变换(Clark变换和Park变换),并给出了相应的Python代码实现。接下来探讨了SVPWM算法的工作机制,包括扇区判断和占空比计算的方法。此外,文章还讨论了电机的PI双闭环控制结构,即速度环和电流环的设计与实现。文中不仅提供了详细的理论背景,还分享了一些实用的编程技巧和注意事项,帮助读者更好地理解和应用这些算法。 适合人群:电气工程专业学生、从事电机控制系统开发的技术人员以及对永磁同步电机控制感兴趣的科研人员。 使用场景及目标:① 学习和掌握永磁同步电机的FOC控制和SVPWM算法的具体实现;② 提供丰富的代码示例和实践经验,便于快速搭建和调试仿真模型;③ 探讨不同参数设置对电机性能的影响,提高系统的稳定性和效率。 其他说明:文章强调了在实际应用中需要注意的一些细节问题,如坐标变换中的系数选择、SVPWM算法中的扇区判断优化以及PI控制器的参数调整等。同时,鼓励读者通过动手实验来加深对各个模块的理解。

    spring-ai-qianfan-1.0.0-M5.jar中文文档.zip

    # 压缩文件中包含: 中文文档 jar包下载地址 Maven依赖 Gradle依赖 源代码下载地址 # 本文件关键字: jar中文文档.zip,java,jar包,Maven,第三方jar包,组件,开源组件,第三方组件,Gradle,中文API文档,手册,开发手册,使用手册,参考手册 # 使用方法: 解压最外层zip,再解压其中的zip包,双击 【index.html】 文件,即可用浏览器打开、进行查看。 # 特殊说明: ·本文档为人性化翻译,精心制作,请放心使用。 ·只翻译了该翻译的内容,如:注释、说明、描述、用法讲解 等; ·不该翻译的内容保持原样,如:类名、方法名、包名、类型、关键字、代码 等。 # 温馨提示: (1)为了防止解压后路径太长导致浏览器无法打开,推荐在解压时选择“解压到当前文件夹”(放心,自带文件夹,文件不会散落一地); (2)有时,一套Java组件会有多个jar,所以在下载前,请仔细阅读本篇描述,以确保这就是你需要的文件;

    Android安全之旅系列博客导读.pdf

    Android逆向过程学习

    【图像处理】基于双目视觉的物体体积测量算法研究附Matlab代码.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。

    3dmax插件按面积分离.ms

    3dmax插件

    spring-ai-autoconfigure-vector-store-qdrant-1.0.0-M7.jar中文文档.zip

    # 【spring-ai-autoconfigure-vector-store-qdrant-1.0.0-M7.jar中文文档.zip】 中包含: 中文文档:【spring-ai-autoconfigure-vector-store-qdrant-1.0.0-M7-javadoc-API文档-中文(简体)版.zip】 jar包下载地址:【spring-ai-autoconfigure-vector-store-qdrant-1.0.0-M7.jar下载地址(官方地址+国内镜像地址).txt】 Maven依赖:【spring-ai-autoconfigure-vector-store-qdrant-1.0.0-M7.jar Maven依赖信息(可用于项目pom.xml).txt】 Gradle依赖:【spring-ai-autoconfigure-vector-store-qdrant-1.0.0-M7.jar Gradle依赖信息(可用于项目build.gradle).txt】 源代码下载地址:【spring-ai-autoconfigure-vector-store-qdrant-1.0.0-M7-sources.jar下载地址(官方地址+国内镜像地址).txt】 # 本文件关键字: spring-ai-autoconfigure-vector-store-qdrant-1.0.0-M7.jar中文文档.zip,java,spring-ai-autoconfigure-vector-store-qdrant-1.0.0-M7.jar,org.springframework.ai,spring-ai-autoconfigure-vector-store-qdrant,1.0.0-M7,org.springframework.ai.vectorstore.qdr

    【ARIMA-WOA-LSTM】差分自回归移动平均方法-鲸鱼优化算法-LSTM预测研究附python代码.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。

    永磁同步电机控制系统中平方根容积卡尔曼滤波(SRCKF)的应用及优化

    内容概要:本文详细介绍了平方根容积卡尔曼滤波(SRCKF)在永磁同步电机(PMSM)控制系统中的应用及其相对于传统CKF的优势。文章首先指出传统CKF在处理协方差矩阵时存在的数值不稳定性和非正定问题,导致系统性能下降。接着,作者通过引入SRCKF,利用Cholesky分解和QR分解来确保协方差矩阵的正定性,从而提高状态估计的精度和稳定性。文中展示了具体的电机模型和状态方程,并提供了详细的代码实现,包括状态预测、容积点生成以及观测更新等关键步骤。此外,文章还分享了实际调试过程中遇到的问题及解决方案,如选择合适的矩阵分解库和处理电机参数敏感性。最终,通过实验数据对比,证明了SRCKF在突加负载情况下的优越表现。 适合人群:从事永磁同步电机控制研究的技术人员、研究生及以上学历的研究者。 使用场景及目标:适用于需要高精度状态估计的永磁同步电机控制系统的设计与优化,特别是在处理非线性问题和提高数值稳定性方面。 其他说明:文章引用了相关领域的权威文献,如Arasaratnam的TAC论文和Zhong的《PMSM无传感器控制综述》,并强调了实际工程实践中代码调试的重要性。

    tokenizers-0.31.1.jar中文文档.zip

    # 【tokenizers-***.jar***文档.zip】 中包含: ***文档:【tokenizers-***-javadoc-API文档-中文(简体)版.zip】 jar包下载地址:【tokenizers-***.jar下载地址(官方地址+国内镜像地址).txt】 Maven依赖:【tokenizers-***.jar Maven依赖信息(可用于项目pom.xml).txt】 Gradle依赖:【tokenizers-***.jar Gradle依赖信息(可用于项目build.gradle).txt】 源代码下载地址:【tokenizers-***-sources.jar下载地址(官方地址+国内镜像地址).txt】 # 本文件关键字: tokenizers-***.jar***文档.zip,java,tokenizers-***.jar,ai.djl.huggingface,tokenizers,***,ai.djl.engine.rust,jar包,Maven,第三方jar包,组件,开源组件,第三方组件,Gradle,djl,huggingface,中文API文档,手册,开发手册,使用手册,参考手册 # 使用方法: 解压 【tokenizers-***.jar***文档.zip】,再解压其中的 【tokenizers-***-javadoc-API文档-中文(简体)版.zip】,双击 【index.html】 文件,即可用浏览器打开、进行查看。 # 特殊说明: ·本文档为人性化翻译,精心制作,请放心使用。 ·只翻译了该翻译的内容,如:注释、说明、描述、用法讲解 等; ·不该翻译的内容保持原样,如:类名、方法名、包名、类型、关键字、代码 等。 # 温馨提示: (1)为了防止解压后路径太长导致浏览器无法打开,推荐在解压时选择“解压到当前文件夹”(放心,自带文件夹,文件不会散落一地); (2)有时,一套Java组件会有多个jar,所以在下载前,请仔细阅读本篇描述,以确保这就是你需要的文件; # Maven依赖: ``` <dependency> <groupId>ai.djl.huggingface</groupId> <artifactId>tokenizers</artifactId> <version>***</version> </dependency> ``` # Gradle依赖: ``` Gradle: implementation group: 'ai.djl.huggingface', name: 'tokenizers', version: '***' Gradle (Short): implementation 'ai.djl.huggingface:tokenizers:***' Gradle (Kotlin): implementation("ai.djl.huggingface:tokenizers:***") ``` # 含有的 Java package(包): ``` ai.djl.engine.rust ai.djl.engine.rust.zoo ai.djl.huggingface.tokenizers ai.djl.huggingface.tokenizers.jni ai.djl.huggingface.translator ai.djl.huggingface.zoo ``` # 含有的 Java class(类): ``` ai.djl.engine.rust.RsEngine ai.djl.engine.rust.RsEngineProvider ai.djl.engine.rust.RsModel ai.djl.engine.rust.RsNDArray ai.djl.engine.rust.RsNDArrayEx ai.djl.engine.rust.RsNDArrayIndexer ai.djl.engine.rust.RsNDManager ai.djl.engine.rust.RsSymbolBlock ai.djl.engine.rust.RustLibrary ai.djl.engine.rust.zoo.RsModelZoo ai.djl.engine.rust.zoo.RsZooProvider ai.djl.huggingface.tokenizers.Encoding ai.djl.huggingface.tokenizers.HuggingFaceTokenizer ai.djl.huggingface.tokenizers.HuggingFaceTokenizer.Builder ai.djl.hu

    3.png

    3

    pchook源码纯源码不是dll

    pchook源码纯源码不是dll

    spring-ai-azure-store-1.0.0-M7.jar中文-英文对照文档.zip

    # 【spring-ai-azure-store-1.0.0-M7.jar中文-英文对照文档.zip】 中包含: 中文-英文对照文档:【spring-ai-azure-store-1.0.0-M7-javadoc-API文档-中文(简体)-英语-对照版.zip】 jar包下载地址:【spring-ai-azure-store-1.0.0-M7.jar下载地址(官方地址+国内镜像地址).txt】 Maven依赖:【spring-ai-azure-store-1.0.0-M7.jar Maven依赖信息(可用于项目pom.xml).txt】 Gradle依赖:【spring-ai-azure-store-1.0.0-M7.jar Gradle依赖信息(可用于项目build.gradle).txt】 源代码下载地址:【spring-ai-azure-store-1.0.0-M7-sources.jar下载地址(官方地址+国内镜像地址).txt】 # 本文件关键字: spring-ai-azure-store-1.0.0-M7.jar中文-英文对照文档.zip,java,spring-ai-azure-store-1.0.0-M7.jar,org.springframework.ai,spring-ai-azure-store,1.0.0-M7,org.springframework.ai.vectorstore.azure,jar包,Maven,第三方jar包,组件,开源组件,第三方组件,Gradle,springframework,spring,ai,azure,store,中文-英文对照API文档,手册,开发手册,使用手册,参考手册 # 使用方法: 解压 【spring-ai-azure-store-1.0.0-M7.jar中文-英文对照文档.zip】,再解

    ### XD/XL系列可编程控制器用户手册硬件篇总结. **手册概述

    内容概要:本文档是关于信捷电气XD、XL系列可编程序控制器的用户手册(硬件篇)。手册详细介绍了该系列PLC的硬件特性,包括产品概述、本体规格参数、系统构成、电源及输入输出规格、运行调试与维护、软元件切换等内容。此外,还提供了丰富的附录信息,如特殊软元件地址及功能、指令一览表、PLC功能配置表和常见问题解答。手册强调了安全操作的重要性,列出了多个安全注意事项,确保用户在正确环境下安装和使用设备,避免潜在风险。 适合人群:具备一定电气知识的专业人士,尤其是从事自动化控制系统设计、安装、调试及维护的技术人员。 使用场景及目标:①帮助用户了解XD、XL系列PLC的硬件特性和规格参数;②指导用户正确安装、接线、调试和维护设备;③提供详细的故障排查指南和技术支持信息,确保设备稳定运行;④为用户提供编程和指令使用的参考资料。 其他说明:手册不仅涵盖了硬件方面的内容,还涉及到了一些基础的软件编程概念,但更深入的编程指导请参考相关软件篇手册。用户在使用过程中遇到问题可以通过提供的联系方式获得技术支持。手册中的内容会定期更新,以适应产品改进和技术发展的需求。

Global site tag (gtag.js) - Google Analytics