Heim  >  Artikel  >  Java  >  Übersicht über Java-Klassenlader und den Klassenladeprozess

Übersicht über Java-Klassenlader und den Klassenladeprozess

王林
王林nach vorne
2023-04-24 10:13:07811Durchsuche

1. Klassenladevorgang

Übersicht über Java-Klassenlader und den Klassenladeprozess

Laden

Übergeben Sie den vollständig qualifizierten Namen der Klasse (Paketname + Klassenname), rufen Sie die Datei .class der Klasse ab und laden Sie sie in den Metaspace. .class文件,加载到元空间。

链接

  • 验证:检验.class文件的安全性

  • 准备:为静态类型变量分配内存并设置默认值

  • 解析:将常量池内的符号引用转换为直接引用,符号引用指向一个未被加载的类,或者未被加载类的字段或方法,那么解析将触发这个类的加载

初始化

执行类的构造器方法init()的过程,若该类具有父类,jvm会保证父类的init先执行,然后在执行子类的init

2. 类加载器

Übersicht über Java-Klassenlader und den Klassenladeprozess

启动类加载器

启动类加载器是由C/C++语言实现的,用来加载Java核心类库。启动类只加载包名为:java、javax、sun开头的类

扩展类加载器

父类加载器为启动类加载器加载以下两个目录中的类库:

  • java.ext.dirs目录

  • JDK安装目录:jre/lib/ext目录

我们就可以将我们自己的包放在以上目录下,就会自动加载进来了。

应用类加载器

父类加载器为启动类加载器,负责加载环境变量classpath或者系统属性java.class.path指定路径下的类库,是程序中默认的类加载器,我们Java程序中的类,都是由它加载完成的。

自定义类加载器

继承java.lang.ClassLoader类,重写findClass()方法 。如果没有太复杂的需求,可以直接继承URLClassLoader类,重写loadClass方法。

作用

  • 加密:Java代码可以轻易的被反编译,如果你需要把自己的代码进行加密以防止反编译,可以先将编译后的代码用某种加密算法加密,类加密后就不能再用Java的ClassLoader去加载类了,这时就需要自定义ClassLoader在加载类的时候先解密类,然后再加载。

  • 从非标准的来源加载代码:如果你的字节码是放在数据库、甚至是在云端,就可以自定义类加载器,从指定的来源加载类。

双亲委派模型

jvm对class文件采用的是按需加载的方式,当需要使用该类时,jvm才会将它的class文件加载到内存中产生class对象。在加载类的时候,是采用的双亲委派机制

  • 如果一个类加载器接收到了类加载的请求,它自己不会先去加载,会把这个请求委托给父类加载器去执行。

  • 如果父类还存在父类加载器,则继续向上委托,一直委托到启动类加载器:Bootstrap ClassLoader

  • 如果父类加载器可以完成加载任务,就返回成功结果,如果父类加载失败,就由子类自己去尝试加载,如果子类加载失败就会抛出ClassNotFoundException异常,这就是双亲委派模式

打破双亲委派模型

用途:

  • Java应用中存在着很多服务提供者接口(Service Provider Interface,SPI),这些接口允许第三方为它们提供实现,如常见的 SPI 有 JDBC、JNDI等,这些 SPI 的接口属于 Java 核心库,一般存在rt.jar包中,由Bootstrap类加载器加载。而Bootstrap类加载器无法直接加载SPI的实现类,所以需要反向委派给其他类加载器进行加载

  • 在Tomcat服务器中,存在一个服务器运行多个不同版本但同名服务的需求,所以需要打破双亲委派模型,加载多个同名类。

方法:

  • 使用上下文类加载器

  • 重写loadClass

    Link
    Überprüfung:Überprüfen Sie .classSicherheit von Dateien#🎜🎜##🎜🎜#
  • #🎜🎜#Vorbereitung:Speicher für statische Typvariablen zuweisen und Standardwerte festlegen#🎜🎜##🎜🎜#
  • # 🎜🎜#Parsing: Konvertieren Sie die Symbolreferenz im Konstantenpool in eine direkte Referenz. Wenn die Symbolreferenz auf eine entladene Klasse oder ein Feld oder eine Methode einer entladenen Klasse verweist, wird dies durch das Parsen ausgelöst Klasse. Laden#🎜🎜##🎜🎜##🎜🎜##🎜🎜#Initialisierung#🎜🎜##🎜🎜#Der Prozess der Ausführung der Konstruktormethode init() der Klasse, wenn Die Klasse hat: Für die übergeordnete Klasse stellt jvm sicher, dass zuerst der init der übergeordneten Klasse und dann der init der Unterklasse ausgeführt wird wird ausgeführt. #🎜🎜##🎜🎜#2. Klassenlader#🎜🎜##🎜🎜#Was ist der Java-Klassenladeprozess und der Klassenlader?#🎜🎜##🎜🎜#Klassenlader starten#🎜🎜##🎜🎜#Der Startklassenlader ist in der Sprache C/C++ implementiert und wird zum Laden verwendet Java-Kernklassenbibliothek. Die Startup-Klasse lädt nur Klassen, deren Paketnamen mit java, javax, sun beginnen >. Laden Sie Klassenbibliotheken in die folgenden zwei Verzeichnisse:#🎜🎜#
    • #🎜🎜#java.ext.dirs code >Directory#🎜🎜##🎜🎜#<li>#🎜🎜#JDK-Installationsverzeichnis: <code>jre/lib/extDirectory#🎜🎜##🎜🎜##🎜🎜##🎜🎜 # Wir können unser eigenes Paket im obigen Verzeichnis ablegen und es wird automatisch geladen. #🎜🎜##🎜🎜#Application Class Loader#🎜🎜##🎜🎜#Der übergeordnete Klassenlader ist Startup Class Loader, der für das Laden von Umgebungsvariablen-Klassenpfad verantwortlich ist oder Systemproperty java.class.path Die Klassenbibliothek unter dem angegebenen Pfad ist der Standard-Klassenlader im Programm. Alle Klassen in unserem Java-Programm werden von ihr geladen. #🎜🎜##🎜🎜#Benutzerdefinierter Klassenlader#🎜🎜##🎜🎜#Erben Sie die Klasse java.lang.ClassLoader und überschreiben Sie die Methode findClass(). Wenn keine zu komplexen Anforderungen vorliegen, können Sie die Klasse URLClassLoader direkt erben und die Methode loadClass überschreiben. #🎜🎜##🎜🎜#Funktion#🎜🎜#
      • #🎜🎜#Verschlüsselung:Java-Code Wenn Sie Ihren Code verschlüsseln müssen, um eine Dekompilierung zu verhindern, können Sie den kompilierten Code zunächst mit einem Verschlüsselungsalgorithmus verschlüsseln. Zu diesem Zeitpunkt können Sie den ClassLoader von Java nicht mehr verwenden , müssen Sie den ClassLoader anpassen, um die Klasse zu entschlüsseln, bevor Sie sie laden. #🎜🎜##🎜🎜#
      • #🎜🎜#Code aus nicht standardmäßigen Quellen laden: Wenn Ihr Bytecode in einer Datenbank oder sogar in der Cloud abgelegt wird, können Sie den Klassenlader anpassen, um Code aus einer angegebenen Quelle zu laden Ladeklasse. #🎜🎜##🎜🎜##🎜🎜##🎜🎜#Parental-Delegierungsmodell#🎜🎜##🎜🎜#jvm verwendet eine On-Demand-Lademethode für Klassendateien, wenn die Klasse verwendet werden muss seine Klassendatei in den Speicher, um ein Klassenobjekt zu generieren. Beim Laden von Klassen wird der Elterndelegierungsmechanismus verwendet. #🎜🎜#
        • #🎜🎜#Wenn ein Klassenlader eine Klassenlade-Anfrage erhält, wird dies der Fall sein Laden Sie es nicht zuerst selbst, sondern delegieren Sie diese Anfrage zur Ausführung an den übergeordneten Klassenlader. #🎜🎜##🎜🎜#
        • #🎜🎜#Wenn die übergeordnete Klasse noch einen übergeordneten Klassenlader hat, delegieren Sie weiter nach oben, bis den Klassenlader startet: Bootstrap ClassLoader#🎜🎜 ## 🎜🎜#
        • #🎜🎜#Wenn der Ladevorgang der übergeordneten Klasse abgeschlossen werden kann, wird ein erfolgreiches Ergebnis zurückgegeben. Wenn das Laden der übergeordneten Klasse fehlschlägt, versucht die untergeordnete Klasse, sie selbst zu laden Wenn die Klasse nicht geladen werden kann, wird eine ClassNotFoundException-Ausnahme ausgelöst. Dies ist das Parental-Delegierungsmodell#🎜🎜##🎜🎜##🎜🎜##🎜🎜#Das übergeordnete Delegationsmodell durchbrechen #🎜🎜##🎜🎜#Zweck:#🎜🎜#
          • #🎜🎜# Es gibt viele Service-Provider-Schnittstellen in Java-Anwendungen (Service Provider Interface, SPI). Zu den gängigen SPIs gehören beispielsweise JDBC, JNDI usw. Diese SPI-Schnittstellen gehören zur Java-Kernbibliothek sind im Allgemeinen im rt.jar-Paket vorhanden und werden vom Bootstrap-Klassenlader gesteuert. Der Bootstrap-Klassenlader kann die SPI-Implementierungsklasse nicht direkt laden, daher muss er zum Laden umgekehrt an andere Klassenlader delegiert werden #🎜🎜##🎜🎜#
          • #🎜🎜#Auf dem Tomcat-Server läuft ein Server Mehrere Es gibt zwei verschiedene Versionen von Diensten mit demselben Namen. Daher ist es erforderlich, das übergeordnete Delegationsmodell zu durchbrechen und mehrere Klassen mit demselben Namen zu laden. #🎜🎜##🎜🎜##🎜🎜##🎜🎜#Methode:#🎜🎜#
            • #🎜🎜#Kontext verwenden Klassenlader #🎜🎜##🎜🎜#
            • #🎜🎜# Überschreibt die loadClass-Methode #🎜🎜##🎜🎜##🎜🎜#

Das obige ist der detaillierte Inhalt vonÜbersicht über Java-Klassenlader und den Klassenladeprozess. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:yisu.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen