Was ist in wenigen einfachen Sätzen ein Java ClassLoader, wann wird er verwendet und warum?
OK, ich habe einen Wiki-Artikel gelesen. ClassLoader lädt Klassen. OK. Wenn ich also JAR-Dateien einbinde und importiere, erledigt ein ClassLoader die Aufgabe.
Warum sollte ich mich mit diesem ClassLoader beschäftigen? Ich habe es nie benutzt und wusste nicht, dass es existiert.
Die Frage ist, warum die ClassLoader-Klasse existiert. Und wie setzen Sie es in der Praxis ein? (Es gibt Fälle, ich weiß.)
java
classloader
EugeneP
quelle
quelle
Antworten:
Entnommen aus diesem schönen Tutorial von Sun:
Motivation
Anwendungen, die in statisch kompilierten Programmiersprachen wie C und C ++ geschrieben sind, werden in native, maschinenspezifische Anweisungen kompiliert und als ausführbare Datei gespeichert. Das Kombinieren des Codes zu einem ausführbaren nativen Code wird als Verknüpfen bezeichnet - das Zusammenführen von separat kompiliertem Code mit gemeinsam genutztem Bibliothekscode, um eine ausführbare Anwendung zu erstellen. Dies unterscheidet sich in dynamisch kompilierten Programmiersprachen wie Java. In Java bleiben die vom Java-Compiler generierten .class-Dateien unverändert, bis sie in die Java Virtual Machine (JVM) geladen werden. Mit anderen Worten, der Verknüpfungsprozess wird von der JVM zur Laufzeit ausgeführt. Klassen werden nach Bedarf in die JVM geladen. Und wenn eine geladene Klasse von einer anderen Klasse abhängt, wird auch diese Klasse geladen.
Wenn eine Java-Anwendung gestartet wird, ist die erste Klasse, die ausgeführt wird (oder der Einstiegspunkt in die Anwendung), die mit der öffentlichen statischen Void-Methode main (). Diese Klasse enthält normalerweise Verweise auf andere Klassen, und alle Versuche, die referenzierten Klassen zu laden, werden vom Klassenladeprogramm ausgeführt.
Betrachten Sie die folgende einfache Klasse, um ein Gefühl für dieses rekursive Laden von Klassen sowie für die Idee des Ladens von Klassen im Allgemeinen zu bekommen:
Wenn Sie diese Klasse mit der Befehlszeilenoption -verbose: class ausführen, damit gedruckt wird, welche Klassen geladen werden, erhalten Sie eine Ausgabe, die wie folgt aussieht. Beachten Sie, dass dies nur eine Teilausgabe ist, da die Liste zu lang ist, um hier angezeigt zu werden.
Wie Sie sehen, werden zuerst die für die Anwendungsklasse (HelloApp) erforderlichen Java-Laufzeitklassen geladen.
Klassenlader in der Java 2-Plattform
Die Programmiersprache Java wird ständig weiterentwickelt, um das Leben der Anwendungsentwickler jeden Tag zu vereinfachen. Dazu werden APIs bereitgestellt, die Ihr Leben vereinfachen, indem Sie sich auf die Geschäftslogik konzentrieren können, anstatt Details grundlegender Mechanismen zu implementieren. Dies wird durch die kürzlich erfolgte Änderung von J2SE 1.5 auf J2SE 5.0 deutlich, um die Reife der Java-Plattform widerzuspiegeln.
Ab JDK 1.2 ist ein in die JVM integrierter Bootstrap-Klassenladeprogramm für das Laden der Klassen der Java-Laufzeit verantwortlich. Dieser Klassenladeprogramm lädt nur Klassen, die im Boot-Klassenpfad gefunden werden. Da es sich um vertrauenswürdige Klassen handelt, wird der Validierungsprozess nicht wie bei nicht vertrauenswürdigen Klassen ausgeführt. Zusätzlich zum Bootstrap-Klassenladeprogramm verfügt die JVM über einen Erweiterungsklassenladeprogramm, das für das Laden von Klassen aus Standarderweiterungs-APIs verantwortlich ist, und ein Systemklassenladeprogramm, das Klassen aus einem allgemeinen Klassenpfad sowie aus Ihren Anwendungsklassen lädt.
Da es mehr als einen Klassenlader gibt, werden sie in einem Baum dargestellt, dessen Stamm der Bootstrap-Klassenlader ist. Jeder Klassenlader hat einen Verweis auf seinen übergeordneten Klassenlader. Wenn ein Klassenlader aufgefordert wird, eine Klasse zu laden, konsultiert er seinen übergeordneten Klassenlader, bevor er versucht, das Element selbst zu laden. Der Elternteil wiederum konsultiert seinen Elternteil und so weiter. Erst wenn alle Klassenlader der Vorfahren die Klasse nicht finden können, wird der aktuelle Klassenlader beteiligt. Mit anderen Worten wird ein Delegierungsmodell verwendet.
Die java.lang.ClassLoader-Klasse
Dies
java.lang.ClassLoader
ist eine abstrakte Klasse, die von Anwendungen in Unterklassen unterteilt werden kann, die die Art und Weise erweitern müssen, in der die JVM Klassen dynamisch lädt. Mit Konstruktoren injava.lang.ClassLoader
(und seinen Unterklassen) können Sie ein übergeordnetes Element angeben, wenn Sie einen neuen Klassenlader instanziieren. Wenn Sie kein übergeordnetes Element explizit angeben, wird der Systemklassenlader der virtuellen Maschine als übergeordnetes Standardelement zugewiesen. Mit anderen Worten, die ClassLoader-Klasse verwendet ein Delegierungsmodell, um nach Klassen und Ressourcen zu suchen. Daher ist jeder Instanz von ClassLoader ein übergeordneter Klassenlader zugeordnet, sodass die Aufgabe bei der Anforderung, eine Klasse oder Ressourcen zu finden, an ihren übergeordneten Klassenlader delegiert wird, bevor versucht wird, die Klasse oder Ressource selbst zu finden. DieloadClass()
Methode des ClassLoader führt die folgenden Aufgaben aus, um beim Laden einer Klasse aufgerufen zu werden:Wenn eine Klasse bereits geladen wurde, gibt sie sie zurück. Andernfalls wird die Suche nach der neuen Klasse an den übergeordneten Klassenlader delegiert. Wenn der übergeordnete Klassenladeprogramm die Klasse nicht findet,
loadClass()
ruft er die MethodefindClass()
zum Suchen und Laden der Klasse auf. DiefinalClass()
Methode sucht im aktuellen Klassenladeprogramm nach der Klasse, wenn die Klasse vom übergeordneten Klassenladeprogramm nicht gefunden wurde.Der Originalartikel enthält weitere Informationen, die Ihnen auch zeigen, wie Sie Ihre eigenen Netzwerkklassenlader implementieren, und die Ihre Frage nach dem Warum (und Wie) beantworten. Siehe auch die API-Dokumente .
quelle
Die meisten Java-Entwickler müssen niemals explizit Klassenladeprogramme verwenden (außer um Ressourcen zu laden, damit es immer noch funktioniert, wenn sie in JARs gebündelt sind), geschweige denn, um ihre eigenen zu schreiben.
ClassLoaders werden in großen Systemen und Serveranwendungen verwendet, um Folgendes zu tun:
quelle
Nun, meistens, damit Sie Dinge reparieren können, wenn sie schief gehen :-).
Es ist wahr, solange Sie nur eine Anwendung schreiben, sie in eine JAR kompilieren und möglicherweise ein paar zusätzliche Bibliotheks-JARs einschließen, müssen Sie nichts über Klassenlader wissen, es wird einfach funktionieren.
Trotzdem ist es hilfreich, etwas über Klassenlader und das Laden von Klassen zu wissen, um besser zu verstehen, was sich hinter den Kulissen abspielt. Beispielsweise werden "statische Initialisierer" ausgeführt, wenn eine Klasse geladen wird. Um zu verstehen, wann sie ausgeführt werden, müssen Sie wissen, wie der Klassenlader entscheidet, wann sie geladen werden sollen.
Für einfache Fälle brauchen Sie sie nicht. Wenn Sie jedoch Code zur Laufzeit dynamisch mit expliziter Kontrolle darüber laden müssen, woher er stammt (z. B. Laden über ein Netzwerk, Laden von Plugins, die zur Kompilierungszeit nicht verfügbar sind usw.), müssen Sie möglicherweise mehr tun. Dann können Sie zB Ihren eigenen Klassenlader schreiben. Siehe die anderen Antworten für Links.
quelle
ClassLoader
in Java ist eine Klasse, die zum Laden von Klassendateien in Java verwendet wird. Java-Code wird vomjavac
Compiler in eine Klassendatei kompiliert, und JVM führt das Java-Programm aus, indem in die Klassendatei geschriebene Bytecodes ausgeführt werden.ClassLoader ist für das Laden von Klassendateien aus dem Dateisystem, dem Netzwerk oder einer anderen Quelle verantwortlich. In Java, Bootstrap , Extension und System- oder Anwendungsklassenlader werden drei Standardklassenlader verwendet .
## ClassLoader-Interaktion mit JVM
Mehr @: how-classloader-works-in-java.html
quelle
Klassenlader sind eine Funktionskomponente von JVM, die Klassendaten aus der '.class'-Datei oder über das Netzwerk in den Methodenbereich in Heap lädt.
Sieht aus wie ein integraler Bestandteil der JVM, aber warum sollte ich als Java-Endbenutzer besorgt sein? Hier ist warum:
Jeder Klassenlader hat seinen eigenen Namensraum und Klassen, die von einem bestimmten Klassenlader aufgerufen werden, gelangen in seinen Namensraum.
Klassen, die von zwei verschiedenen Klassenladeprogrammen aufgerufen werden, sind nicht übereinander sichtbar, was zu einer erhöhten Sicherheit führt.
Der übergeordnete untergeordnete Delegierungsmechanismus des Klassenladeprogramms stellt sicher, dass Java-API-Klassen niemals von nicht autorisiertem Code gehackt werden können.
Details finden Sie hier
quelle
Klassenlader sind hierarchisch. Klassen werden in die JVM eingeführt, da sie in einer Klasse, die bereits in der JVM ausgeführt wird, namentlich referenziert werden.
Wie wurde die allererste Klasse geladen?
Die allererste Klasse wird mit Hilfe der
static main()
in Ihrer Klasse deklarierten Methode geladen . Alle anschließend geladenen Klassen werden von den Klassen geladen, die bereits geladen sind und ausgeführt werden.Ein Klassenladeprogramm erstellt einen Namespace. Alle JVM enthalten mindestens einen Klassenlader, der in die JVM eingebettet ist und als primordialer (oder Bootstrap-) Klassenlader bezeichnet wird. Das ist eine Sache, und wir werden uns nicht-ursprüngliche Klassenlader ansehen. Die JVM verfügt über Hooks, mit denen benutzerdefinierte Klassenlader anstelle des ursprünglichen Klassenladers verwendet werden können. Hier sind die von der JVM erstellten Klassenlader.
Bootstrap (primordial) Dieser Klassenlader kann nicht wieder geladen werden. Lädt JDK-interne Klassen, Java. * -Pakete (lädt normalerweise rt.jar und i18n.jar). Erweiterungen Dieser Klassenlader kann nicht wieder geladen werden. Lädt JAR-Dateien aus dem JDK-Erweiterungsverzeichnis (normalerweise lib / ext von JRE). System Dieser Klassenlader kann nicht wieder geladen werden. Lädt Klassen aus dem Systemklassenpfad.
http://www.sbalasani.com/2015/01/java-class-loaders.html
quelle
Wenn Sie fragen, warum die ClassLoader-Klasse vorhanden ist, ist der Grund ziemlich einfach: Es ist die Klasse, die zum Suchen und Laden von Klassendateien zur Laufzeit verantwortlich ist .
Lassen Sie es uns näher erläutern.
In JVM wird jede Klasse von einer Instanz von geladen
java.lang.ClassLoader
. Immer wenn eine neue JVM von Ihrem üblichen Java-Programmstartbefehl gestartet wirdjava <classname>
, besteht der erste Schritt darin, alle Schlüsselklassen in den Speicher zu laden, die für ein ordnungsgemäßes Funktionieren wiejava.lang.Object
andere Laufzeitklassen erforderlich sind (rt.jar
).ClassLoader besteht nun aus drei Teilen:
Der
BootstrapClassLoader
ist dafür verantwortlich, diese Klassen verfügbar zu machen, dh diese Klassen in den Speicher zu laden.Die nächste Aufgabe besteht darin, externe Bibliotheken / JARs in den Speicher zu laden, damit die Anwendung ordnungsgemäß funktioniert. Der
ExtClassLoader
ist für diese Aufgabe verantwortlich. Dieser Klassenladeprogramm ist für das Laden aller im Pfad java.ext.dirs genannten .jar-Dateien verantwortlich.Der dritte und wichtigste Klassenlader ist der
AppClassLoader
. Der Application Class Loader ist für das Laden der in der Systemeigenschaft java.class.path genannten Klassendateien verantwortlich.Es ist auch wichtig zu beachten, dass die Standard-ClassLoader-Implementierungen überschrieben werden können, sodass Sie die JVM auf nützliche und interessante Weise anpassen und die Art und Weise, wie Klassendateien in das System gebracht werden, vollständig neu definieren können.
Erfahren Sie mehr über Java Class Loader .
quelle