2011-09-30 12 views
9

Teniendo en cuenta este código:.Diferencia entre ClassLoader.getSystemResourceAsStream y getClass() getResourceAsStream()

/* 1 */ InputStream in1 = ClassLoader.getSystemResourceAsStream("foobar.txt"); 
/* 2 */ InputStream in2 = this.getClass().getResourceAsStream("/foobar.txt"); 

hacer ambas devuelven el mismo recurso (creo que el "sí" la respuesta)?

¿Ambos acceden al "mismo" classpath? ¿Por qué el nombre del método en # 1 "obtiene Sistema ResourceAsStream", pero para el # 2 es solo "getResourceAsStream"?

Gracias

Respuesta

7

De acuerdo con el javadoc

abierto para la lectura, un recurso con el nombre especificado de la ruta de búsqueda utilizan para cargar las clases. Este método ubica el recurso a través del el cargador de clases del sistema (ver getSystemClassLoader()).

El cargador de clases utilizado para cargar this no es necesariamente el cargador de clases del sistema. En una aplicación de escritorio simple, esto probablemente sea cierto. Pero las webapps, entre otras cosas, suelen tener jerarquías de classpath más complejas, por lo que no necesariamente serán las mismas. En un classpath complejo, por lo tanto, lo que se devuelve también dependerá de cuántas copias de 'foobar.txt' están flotando alrededor de su classpath.

La respuesta corta es que no puede suponer que devolverán una secuencia para el mismo recurso.

+0

¿Entonces usted dice que hay múltiples classpaths en las aplicaciones web? – Michael

+0

@Michael - Más o menos. Normalmente, cada aplicación web tiene su propio cargador de clases que es responsable de los contenidos de WAR, EAR, etc. Estos cargadores de clases tienen un elemento primario común y, por lo tanto, las clases en los directorios lib comunes se comparten entre las diversas aplicaciones web. Pero estas jerarquías pueden ser de varios cargadores de profundidad. El cargador de clases del sistema estará en la parte superior, pero quizás haya un número intermedio. – sblundy

+0

Diferentes webapps probablemente tengan diferentes cargadores de clases. Por ejemplo, en Glassfish, tienen una jerarquía especificada aquí: http://download.oracle.com/docs/cd/E19798-01/821-1752/6nmndgmhr/index.html#fvxzq. – g051051

11

La diferencia clave es el cargador de clases.

El siguiente utiliza el cargador de clases Sistema
ClassLoader.getSystemResourceAsStream("foobar.txt");

Mientras que éste utiliza el cargador de clases devuelto por getClass()
this.getClass().getResourceAsStream("/foobar.txt");

En otras palabras, si los dos estados se comportan exactamente de la misma o no, depende de la cargador de clases de la aplicación. Para una aplicación simple, ambos se refieren al mismo cargador de clases. Sin embargo, para la mayoría de las aplicaciones (como una aplicación web que se ejecuta dentro del contenedor Servlet), ese no será el caso.

En general, diría que getClass(). GetResourceAsStream() será la mejor opción ya que usará el mismo cargador de clases que la clase a la que pertenece el código.

Cuestiones relacionadas