Java >> Java tutorial >  >> Tag >> class

Forskellen mellem trådens kontekstklasse-loader og normal klasse-loader

1. Oversigt

Java bruger forskellige typer klasseindlæsere til at indlæse ressourcer under programafvikling. I dette selvstudie vil vi undersøge forskellen i adfærden af ​​nuværende og trådklasseindlæsere i Java.

2. Hvad gør en klasseindlæser?

Java-klasseindlæsere finder og indlæser de klasser, der kræves til applikationsudførelse. Hvis den anmodede klasse er afhængig af andre ressourcer, indlæses de også.

Vi har brug for passende klasseindlæsere til indlæsning af forskellige typer klasser, når det er nødvendigt af Java-programmer .

3. Forholdet mellem klasselæsere

Java-klasseindlæsere følger et hierarkisk forhold .

Hver anmodning om at finde eller indlæse en klasse delegeres til den respektive overordnede klasseindlæser. Hvis alle forfaderklasseindlæsere ikke er i stand til at finde en klasse, så forsøger den aktuelle klasseindlæser at finde den. Her betyder "aktuel klasse" klassen for den aktuelt eksekverende metode.

Dette forhold mellem klasseindlæsere hjælper med at bevare det unikke ved ressourcer i en applikation. Derudover, hvis en klasse allerede er blevet indlæst af en overordnet klasseindlæser, behøver den underordnede klasseindlæser ikke at genindlæse den.

4. Standard klasseindlæsere

Klasseindlæsere indlæser klasser og ressourcer, der findes på deres respektive klassesti:

  • System- eller applikationsklasseindlæsere indlæser klasser fra applikationsklassestien
  • Udvidelsesklasseindlæsere søger på Extension-klassestien (JRE/lib/ext )
  • Bootstrap-klasseindlæseren ser på Bootstrap-klassestien (JRE/lib/rt.jar )

En Bootstrap- eller Primordial-klasseindlæser er overordnet til alle klasseindlæsere. Den indlæser Java-runtiden – de klasser, der kræves for at køre selve JVM.

Nuværende klasseindlæsere søger efter ressourcer på en lineær, hierarkisk måde. Hvis en klasseindlæser ikke kan finde en klasse, kaster den java.lang.ClassNotFoundException til den tilsvarende barneklasselæsser. Den underordnede klasseindlæser forsøger derefter at søge efter klassen.

For scenarier, hvor nødvendige ressourcer ikke findes på klassestier for nogen af ​​klasseindlæserne i hierarkiet, får vi fejlmeddelelser relateret til java.lang.ClassNotFoundException som slutresultat.

Vi kan også tilpasse standardindlæsningsadfærden for klassen. Vi kan eksplicit angive klasseindlæseren, mens vi indlæser en klasse dynamisk .

Vi skal dog bemærke, at hvis vi indlæser den samme klasse fra forskellige typer klasseindlæsere, vil disse blive set som forskellige ressourcer af JVM.

5. Kontekstklasseindlæsere

Udover standardklasseindlæserne, introducerede J2SE også kontekstklasseindlæsere.

Hver t tråd i Java har en tilknyttet kontekstklasseindlæser .

Vi kan få adgang til/ændre kontekstklasseindlæseren for en tråd ved hjælp af getContextClassLoader() og setContextClassLoader() metoder for tråden klasse.

Kontekstklasseindlæseren indstilles på tidspunktet for oprettelsen af ​​en tråd. Hvis det ikke er angivet eksplicit, er det standard til kontekstklasseindlæseren for den overordnede tråd .

Kontekstklasseindlæsere følger også hierarkimodellen. Rodklasseindlæseren, i dette tilfælde, er kontekstklasseindlæseren af ​​den oprindelige tråd. En primordial tråd er den indledende tråd, der er oprettet af operativsystemet.

Når programmet begynder at køre, kan andre tråde blive oprettet. Kontekstklasseindlæseren for en primordial tråd er oprindeligt indstillet til den klasseindlæser, der indlæser applikationen, dvs. systemklasseindlæseren.

Antag, at vi ikke opdaterer kontekstklasseindlæseren for nogen tråd på noget niveau i hierarkiet. Som et resultat kan vi sige, at kontekstklasseindlæseren for en tråd som standard er den samme som systemklasseindlæseren. For sådanne scenarier, hvis vi udfører Thread.currentThread().getContextClassLoader() og getClass().getClassLoader() operationer, vil begge returnere de samme objekter.

5.1. Håndter problemer med delegation

Kontekstklasseindlæsere er vigtige, når de nødvendige ressourcer ikke er til stede på klassestien for standard Java-klasseindlæsere. Derfor kan vi bruge kontekstklasseindlæsere til at afvige fra den traditionelle lineære delegationsmodel .

I den hierarkiske model af klasseindlæsere er ressourcer indlæst af overordnede klasseindlæsere synlige for de underordnede klasseindlæsere, men ikke omvendt. I nogle scenarier skal overordnede klasseindlæsere muligvis få adgang til klasser, der findes på klassestien for underordnede klasseindlæsere.

Kontekstklasseindlæsere er et nyttigt værktøj til at få dette til at ske. Vi kan indstille kontekstklasseindlæseren til den ønskede værdi, når vi får adgang til de nødvendige ressourcer. Derfor kan vi i ovenstående tilfælde bruge undertrådens kontekstklasseindlæser og kan lokalisere de ressourcer, der findes på underordnet klasseindlæserniveau.

5.2. Multimodulmiljø

Mens du indstiller kontekstklassens loader-egenskab, skifter vi grundlæggende konteksten for indlæsning af ressourcer . I stedet for at søge på den aktuelle klassesti, henter vi en ny klasseindlæser, der peger på en anden klassesti. Dette er især nyttigt, hvis vi ønsker at indlæse ressourcer fra et tredjepartsmodul, eller hvis vi arbejder i et miljø med forskellige klassenavneområder.

Men vi bør udvise forsigtighed her og nulstille kontekstklassens loader-egenskab tilbage til den oprindelige klasse-loader for at undgå fremtidige uoverensstemmelser.

6. Konklusion

I denne artikel har vi analyseret betydningen af ​​at bruge kontekstklasseindlæsere til at indlæse ressourcer, der ikke er tilgængelige via normale klasseindlæsere. Vi så, at vi også kunne vælge midlertidigt at opdatere kontekstklasseindlæseren for en given tråd til indlæsning af påkrævede klasser.

Det er vigtigt at forstå den kontekst, som den nuværende metode fungerer i. Vi kan have ressourcer med samme navn på forskellige klassestier. Derfor bør vi udvise forsigtighed, mens vi indlæser ressourcer fra flere klasseindlæsere.


Java tag