java - tutorial - spring classloader
¿Qué es un Java ClassLoader? (6)
La pregunta es "¿Por qué debería uno molestar a esta clase ClassLoader existe"?
Bueno, principalmente para que puedas arreglar las cosas si salen mal :-).
Es verdad, siempre que solo escriba una aplicación, la compile en un JAR y tal vez incluya algunos JAR de biblioteca adicionales, no necesita saber acerca de los cargadores de clase, simplemente funcionará.
Aún así, es útil saber un poco sobre los cargadores de clases y la carga de clases para comprender mejor lo que sucede detrás de escena. Como ejemplo, los "inicializadores estáticos" se ejecutarán cuando se cargue una clase, por lo que para saber cuándo se ejecutarán, debe saber cómo el cargador de clases decide cuándo cargarlos.
también ... ¿cómo lo usas en la práctica?
Para casos simples, no los necesitas. Sin embargo, si necesita cargar código dinámicamente en tiempo de ejecución con control explícito de dónde proviene (por ejemplo, cargando en una red, cargando complementos no disponibles en tiempo de compilación, etc.), es posible que necesite hacer más. Entonces puede, por ejemplo, escribir su propio cargador de clases. Ver las otras respuestas para enlaces.
En algunas oraciones simples, ¿qué es un Java ClassLoader, cuándo se usa y por qué?
OK, leí un artículo de wiki. ClassLoader carga clases. DE ACUERDO. Entonces, si incluyo archivos jar e importo, un ClassLoader hace el trabajo.
¿Por qué debería molestarme con este ClassLoader? Nunca lo he usado y no sabía que existía.
La pregunta es, ¿por qué existe la clase ClassLoader? Y también, ¿cómo lo usas en la práctica? (Los casos existen, lo sé)
La mayoría de los desarrolladores de Java nunca necesitarán usar explícitamente cargadores de clases (excepto para cargar recursos para que aún funcione cuando están empaquetados en JAR), y mucho menos escribir los suyos propios.
Los ClassLoaders se utilizan en sistemas grandes y aplicaciones de servidor para hacer cosas como:
- Modular un sistema y cargar, descargar y actualizar módulos en tiempo de ejecución
- Utilice diferentes versiones de una biblioteca API (por ejemplo, un analizador XML) en paralelo
- Aísle diferentes aplicaciones que se ejecutan dentro de la misma JVM (asegurándose de que no interfieran entre sí, por ejemplo, a través de variables estáticas)
Los cargadores de clase son jerárquicos. Las clases se introducen en la JVM, ya que se hace referencia a ellas por nombre en una clase que ya se está ejecutando en la JVM.
¿Cómo se cargó la primera clase?
La primera clase se carga con la ayuda del método static main()
declarado en su clase. Todas las clases cargadas posteriormente son cargadas por las clases, que ya están cargadas y en ejecución.
Un cargador de clases crea un espacio de nombres. Todas las JVM incluyen al menos un cargador de clases que está incrustado dentro de la JVM llamado el cargador de clases primordial (o bootstrap) . Esa es una cosa, y vamos a mirar cargadores de clases no primordiales. La JVM tiene ganchos para permitir el uso de cargadores de clases definidos por el usuario en lugar del cargador de clases primordial. Aquí están los cargadores de clase creados por JVM.
Bootstrap (primordial) Este cargador de clase no se puede cargar. Carga paquetes de clases internas JDK, java. * (Normalmente carga rt.jar e i18n.jar). Extesions Este cargador de clase no se puede cargar. Carga archivos jar del directorio de extensiones JDK (generalmente lib / ext de JRE). Sistema Este cargador de clase no se puede cargar. Carga clases desde la ruta de clase del sistema.
Los cargadores de clase son un componente funcional de JVM, que carga datos de clase del archivo ''.class'' o de la red en el área de métodos en Heap.
Parece una parte integral de la JVM, pero como usuario final de Java, ¿por qué debería preocuparme? Aquí es por qué:
Cada cargador de clases tiene su propio espacio de nombres y las clases invocadas por un cargador de clases particular entran en su espacio de nombres.
Las clases invocadas por dos cargadores de clases diferentes no tendrán visibilidad una sobre la otra, lo que dará como resultado una seguridad mejorada.
El mecanismo de delegación padre-hijo del cargador de clases asegura que las clases java api nunca puedan ser pirateadas por código no autorizado.
Para detalles, mira here
Tomado de este lindo tutorial de Sun:
Motivación
Las aplicaciones escritas en lenguajes de programación compilados estáticamente, como C y C ++, se compilan en instrucciones nativas, específicas de la máquina y se guardan como un archivo ejecutable. El proceso de combinar el código en un código nativo ejecutable se denomina vinculación: la combinación de código compilado por separado con código de biblioteca compartida para crear una aplicación ejecutable. Esto es diferente en lenguajes de programación compilados dinámicamente como Java. En Java, los archivos .class generados por el compilador de Java permanecen tal cual hasta que se carguen en la Máquina Virtual Java (JVM), en otras palabras, el proceso de enlace lo realiza la JVM en tiempo de ejecución. Las clases se cargan en la JVM según sea necesario. Y cuando una clase cargada depende de otra clase, esa clase también se carga.
Cuando se lanza una aplicación Java, la primera clase que se ejecuta (o el punto de entrada en la aplicación) es la que tiene el método de vacío público estático denominado main (). Esta clase generalmente tiene referencias a otras clases, y todos los intentos de cargar las clases referenciadas son llevados a cabo por el cargador de clases.
Para tener una idea de esta carga de clase recursiva, así como también de la idea de carga de clase en general, considere la siguiente clase simple:
public class HelloApp {
public static void main(String argv[]) {
System.out.println("Aloha! Hello and Bye");
}
}
Si ejecuta esta clase especificando la opción de línea de comandos -verbose: class, para que imprima qué clases se están cargando, obtendrá un resultado que se verá de la siguiente manera. Tenga en cuenta que esto es solo un resultado parcial, ya que la lista es demasiado larga para mostrarla aquí.
prmpt>java -verbose:class HelloApp
[Opened C:/Program Files/Java/jre1.5.0/lib/rt.jar]
[Opened C:/Program Files/Java/jre1.5.0/lib/jsse.jar]
[Opened C:/Program Files/Java/jre1.5.0/lib/jce.jar]
[Opened C:/Program Files/Java/jre1.5.0/lib/charsets.jar]
[Loaded java.lang.Object from shared objects file]
[Loaded java.io.Serializable from shared objects file]
[Loaded java.lang.Comparable from shared objects file]
[Loaded java.lang.CharSequence from shared objects file]
[Loaded java.lang.String from shared objects file]
[Loaded java.lang.reflect.GenericDeclaration from shared objects file]
[Loaded java.lang.reflect.Type from shared objects file]
[Loaded java.lang.reflect.AnnotatedElement from shared objects file]
[Loaded java.lang.Class from shared objects file]
[Loaded java.lang.Cloneable from shared objects file]
[Loaded java.lang.ClassLoader from shared objects file]
[Loaded java.lang.System from shared objects file]
[Loaded java.lang.Throwable from shared objects file]
.
.
.
[Loaded java.security.BasicPermissionCollection from shared objects file]
[Loaded java.security.Principal from shared objects file]
[Loaded java.security.cert.Certificate from shared objects file]
[Loaded HelloApp from file:/C:/classes/]
Aloha! Hello and Bye
[Loaded java.lang.Shutdown from shared objects file]
[Loaded java.lang.Shutdown$Lock from shared objects file]
Como puede ver, las clases de tiempo de ejecución de Java requeridas por la clase de aplicación (HelloApp) se cargan primero.
Cargadores de clase en la plataforma Java 2
El lenguaje de programación Java sigue evolucionando para hacer que la vida de los desarrolladores de aplicaciones sea más fácil todos los días. Esto se hace proporcionando API que simplifican su vida al permitirle concentrarse en la lógica comercial en lugar de los detalles de implementación de los mecanismos fundamentales. Esto es evidente por el cambio reciente de J2SE 1.5 a J2SE 5.0 para reflejar la madurez de la plataforma Java.
A partir de JDK 1.2, un cargador de clases de arranque incorporado en la JVM es responsable de cargar las clases del tiempo de ejecución de Java. Este cargador de clases solo carga las clases que se encuentran en el classpath de inicio, y dado que estas son clases de confianza, el proceso de validación no se realiza como para las clases que no son de confianza. Además del cargador de clases de arranque, la JVM tiene un cargador de clases de extensión responsable de cargar las clases desde las API de extensión estándar, y un cargador de clases del sistema que carga las clases desde una ruta de clase general, así como sus clases de aplicación.
Como hay más de un cargador de clases, se representan en un árbol cuya raíz es el cargador de clases de arranque. Cada cargador de clases tiene una referencia a su cargador de clases padre. Cuando se solicita a un cargador de clases que cargue una clase, consulta su cargador de clases principal antes de intentar cargar el elemento. El padre a su vez consulta a su padre, y así sucesivamente. Entonces, después de todo, los cargadores de clase ancestros no pueden encontrar la clase en la que se involucra el cargador de clases actual. En otras palabras, se usa un modelo de delegación.
La clase java.lang.ClassLoader
java.lang.ClassLoader
es una clase abstracta que puede subclasificarse mediante aplicaciones que necesitan ampliar la manera en que la JVM carga dinámicamente las clases. Los constructores en java.lang.ClassLoader
(y sus subclases) le permiten especificar un elemento primario al instanciar un nuevo cargador de clases. Si no especifica explícitamente un elemento principal, el cargador de clases del sistema de la máquina virtual se asignará como el elemento primario predeterminado. En otras palabras, la clase ClassLoader usa un modelo de delegación para buscar clases y recursos. Por lo tanto, cada instancia de ClassLoader tiene un cargador de clases principal asociado, de modo que cuando se le solicite encontrar una clase o recursos, la tarea se delegue en su cargador de clases principal antes de intentar encontrar la clase o el recurso en sí. El método loadClass()
del ClassLoader realiza las siguientes tareas, en orden, cuando se le llama para cargar una clase:
Si una clase ya se ha cargado, la devuelve. De lo contrario, delega la búsqueda de la nueva clase en el cargador de clases padre. Si el cargador de clases padre no encuentra la clase, loadClass()
llama al método findClass()
para buscar y cargar la clase. El método finalClass()
busca la clase en el cargador de clases actual si el cargador de clases padre no encontró la clase.
Hay más en el artículo original, que también le muestra cómo implementar sus propios cargadores de clase de red, que responde a su pregunta sobre por qué (y cómo). Ver también los documentos API .
ClassLoader
en Java es una clase que se utiliza para cargar archivos de clase en Java. El compilador javac
compila el código Java en el archivo de clase y JVM ejecuta el programa Java ejecutando los códigos de bytes escritos en el archivo de clase.
ClassLoader es responsable de cargar los archivos de clase desde el sistema de archivos, la red o cualquier otra fuente. Hay tres cargadores de clases predeterminados utilizados en Java, Bootstrap , Extension y System o Application class loader.