Resources
Recursos
Este capítulo explica cómo Spring gestiona los recursos y cómo puedes trabajar con ellos. Incluye los temas siguientes:
- Introducción.
- La interfaz
Resource. - Implementaciones integradas de
Resource. - La interfaz
ResourceLoader. - La interfaz
ResourcePatternResolver. - La interfaz
ResourceLoaderAware. - Recursos como dependencias.
- Contextos de aplicación y rutas de recursos.
Introducción
La clase estándar java.net.URL de Java y los controladores estándar de los distintos prefijos de URL no resultan suficientes para todos los accesos a recursos de bajo nivel. Por ejemplo, no existe una implementación estándar de URL para acceder a un recurso obtenido desde el classpath o relativo a un ServletContext.
Aunque es posible registrar nuevos controladores para prefijos de URL especializados —de forma similar a los controladores existentes para prefijos como http:—, normalmente resulta complicado. Además, la interfaz URL carece de funciones útiles, como un método para comprobar si el recurso señalado existe.
La interfaz Resource
La interfaz Resource de Spring, situada en el paquete org.springframework.core.io, ofrece una abstracción más completa para acceder a recursos de bajo nivel:
public interface Resource extends InputStreamSource {
boolean exists();
boolean isReadable();
boolean isOpen();
boolean isFile();
URL getURL() throws IOException;
URI getURI() throws IOException;
File getFile() throws IOException;
ReadableByteChannel readableChannel() throws IOException;
long contentLength() throws IOException;
long lastModified() throws IOException;
Resource createRelative(String relativePath) throws IOException;
String getFilename();
String getDescription();
}
Resource amplía la interfaz InputStreamSource:
public interface InputStreamSource {
InputStream getInputStream() throws IOException;
}
Entre los métodos más importantes de Resource se encuentran:
getInputStream(): localiza y abre el recurso, y devuelve unInputStreampara leerlo. Cada invocación debe devolver un flujo nuevo. Quien realiza la llamada debe cerrarlo.exists(): indica mediante unbooleansi el recurso existe físicamente.isOpen(): indica si el recurso representa un descriptor con un flujo abierto. Si devuelvetrue, elInputStreamno puede leerse varias veces: debe leerse una sola vez y cerrarse para evitar fugas de recursos. Devuelvefalsepara las implementaciones habituales, salvoInputStreamResource.getDescription(): devuelve una descripción para utilizarla en mensajes de error al trabajar con el recurso. A menudo es el nombre de archivo totalmente cualificado o la URL real.
Otros métodos permiten obtener un URL o un objeto File que represente el recurso, siempre que la implementación subyacente sea compatible.
Algunas implementaciones de Resource también implementan WritableResource, una interfaz ampliada para recursos que admiten escritura.
Spring utiliza ampliamente la abstracción Resource, por ejemplo, como tipo de argumento en muchas firmas de métodos que necesitan un recurso. Otros métodos de la API de Spring, como los constructores de varias implementaciones de ApplicationContext, aceptan un String: en su forma simple, ese valor se usa para crear un Resource adecuado para el contexto; mediante prefijos especiales en la ruta, también puedes exigir una implementación concreta de Resource.
Aunque Spring utiliza mucho Resource, también resulta útil como clase de utilidad general para acceder a recursos desde tu propio código, incluso cuando este no depende de otras partes de Spring. El acoplamiento se limita a un pequeño conjunto de clases utilitarias que puede considerarse un sustituto más completo de URL.
La abstracción Resource no reemplaza la funcionalidad existente; la envuelve cuando es posible. Por ejemplo, UrlResource envuelve una URL y utiliza esa URL para realizar su trabajo.
Implementaciones integradas de Resource
Spring incluye estas implementaciones integradas:
UrlResourceClassPathResourceFileSystemResourcePathResourceServletContextResourceInputStreamResourceByteArrayResource
Para obtener la lista completa de implementaciones disponibles, consulta la sección All Known Implementing Classes del Javadoc de Resource.
UrlResource
UrlResource envuelve un java.net.URL y permite acceder a cualquier objeto normalmente accesible mediante una URL, como archivos, destinos HTTPS, destinos FTP y otros.
Todas las URL tienen una representación estándar como String, mediante prefijos que distinguen su tipo. Incluyen file: para rutas del sistema de archivos, https: para recursos servidos mediante HTTPS, ftp: para recursos FTP y otros.
Puedes crear un UrlResource explícitamente mediante su constructor. Sin embargo, con frecuencia se crea implícitamente al llamar a una API que recibe un String que representa una ruta. En ese caso, un PropertyEditor de JavaBeans determina qué tipo de Resource debe crear.
Si la cadena contiene un prefijo conocido por el editor de propiedades —por ejemplo, classpath:—, se crea el Resource especializado correspondiente. Si no reconoce el prefijo, supone que es una URL estándar y crea un UrlResource.
ClassPathResource
ClassPathResource representa un recurso que debe obtenerse desde el classpath. Utiliza el cargador de clases del contexto del hilo, un cargador de clases proporcionado o una clase proporcionada para cargar los recursos.
Esta implementación permite resolverse como java.io.File si el recurso del classpath reside en el sistema de archivos. No lo permite si el recurso está dentro de un JAR que no se ha expandido al sistema de archivos. Para cubrir este caso, las implementaciones de Resource siempre admiten la resolución como java.net.URL.
Puedes crear un ClassPathResource explícitamente mediante su constructor o de forma implícita usando el prefijo classpath: en una ruta String.
FileSystemResource
FileSystemResource es una implementación de Resource para identificadores java.io.File. También admite identificadores java.nio.file.Path: aplica las transformaciones estándar de rutas basadas en String de Spring, pero realiza las operaciones mediante la API java.nio.file.Files.
Para una compatibilidad exclusivamente basada en java.nio.file.Path, utiliza PathResource. FileSystemResource admite resolución como File y como URL.
PathResource
PathResource es una implementación de Resource para identificadores java.nio.file.Path. Ejecuta las operaciones y transformaciones mediante la API Path.
Admite resolución como File y URL, y también implementa WritableResource. Es una alternativa puramente basada en Path a FileSystemResource, con un comportamiento distinto en createRelative.
ServletContextResource
ServletContextResource representa recursos de un ServletContext e interpreta las rutas relativas dentro del directorio raíz de la aplicación web correspondiente.
Siempre admite acceso por flujo y por URL. Solo permite acceso mediante java.io.File cuando el archivo WAR se ha expandido y el recurso reside físicamente en el sistema de archivos. Que el recurso esté expandido, se lea directamente desde un JAR o proceda de otra ubicación depende del contenedor Servlet.
InputStreamResource
InputStreamResource es una implementación de Resource para un InputStream determinado. Debe utilizarse solo cuando no sea aplicable una implementación más específica. Siempre que sea posible, prefiere ByteArrayResource o alguna implementación basada en archivos.
A diferencia de otras implementaciones de Resource, describe un recurso ya abierto. Por tanto, isOpen() devuelve true. No la utilices si necesitas conservar el descriptor de recurso o leer el flujo varias veces.
ByteArrayResource
ByteArrayResource es una implementación de Resource para un array de bytes. Crea un ByteArrayInputStream para el array proporcionado.
Es útil para cargar contenido de cualquier array de bytes sin recurrir a un InputStreamResource de un solo uso.
La interfaz ResourceLoader
La interfaz ResourceLoader la implementan los objetos capaces de devolver —es decir, cargar— instancias de Resource:
public interface ResourceLoader {
Resource getResource(String location);
ClassLoader getClassLoader();
}
Todos los contextos de aplicación implementan ResourceLoader. Por tanto, puedes utilizar cualquier ApplicationContext para obtener instancias de Resource.
Cuando llamas a getResource() en un contexto de aplicación y la ruta no tiene un prefijo específico, recibes un tipo de Resource apropiado para ese contexto. Por ejemplo:
Resource template = ctx.getResource("some/resource/path/myTemplate.txt");
En un ClassPathXmlApplicationContext, este código devuelve un ClassPathResource. En un FileSystemXmlApplicationContext, devuelve un FileSystemResource. En un WebApplicationContext, devuelve un ServletContextResource.
También puedes forzar el uso de ClassPathResource, sin importar el tipo de contexto, con el prefijo classpath::
Resource template =
ctx.getResource("classpath:some/resource/path/myTemplate.txt");
Del mismo modo, puedes forzar un UrlResource utilizando prefijos estándar de java.net.URL:
Resource template =
ctx.getResource("file:///some/resource/path/myTemplate.txt");
Resource template =
ctx.getResource("https://myhost.com/resource/path/myTemplate.txt");
La siguiente tabla resume la conversión de String a Resource:
| Prefijo | Ejemplo | Explicación |
|---|---|---|
classpath: |
classpath:com/myapp/config.xml |
Se carga desde el classpath. |
file: |
file:///data/config.xml |
Se carga como una URL desde el sistema de archivos. |
https: |
https://myserver/logo.png |
Se carga como una URL. |
| Sin prefijo | /data/config.xml |
Depende del ApplicationContext subyacente. |
La interfaz ResourcePatternResolver
ResourcePatternResolver amplía ResourceLoader y define una estrategia para resolver patrones de ubicación —por ejemplo, rutas con estilo Ant— en objetos Resource:
public interface ResourcePatternResolver extends ResourceLoader {
String CLASSPATH_ALL_URL_PREFIX = "classpath*:";
Resource[] getResources(String locationPattern) throws IOException;
}
Esta interfaz define también el prefijo especial classpath*: para obtener todos los recursos coincidentes del classpath. En este caso, la ubicación debe ser una ruta sin marcadores de posición, por ejemplo classpath*:/config/beans.xml. Distintos JAR o directorios del classpath pueden contener varios archivos con la misma ruta y el mismo nombre.
Puedes comprobar si un ResourceLoader proporcionado —por ejemplo, mediante ResourceLoaderAware— implementa también esta interfaz ampliada.
PathMatchingResourcePatternResolver es una implementación independiente que puede utilizarse fuera de un ApplicationContext. También la usa ResourceArrayPropertyEditor para rellenar propiedades de beans de tipo Resource[].
PathMatchingResourcePatternResolver puede resolver una ruta en uno o varios objetos Resource. La ruta puede ser una ruta simple, con correspondencia uno a uno, o contener el prefijo classpath*: y expresiones internas de estilo Ant, que se comparan mediante org.springframework.util.AntPathMatcher. Los dos últimos casos actúan como comodines.
El ResourceLoader predeterminado de cualquier ApplicationContext estándar es una instancia de PathMatchingResourcePatternResolver. El propio ApplicationContext también implementa ResourcePatternResolver y delega en ese resolvedor predeterminado.
La interfaz ResourceLoaderAware
ResourceLoaderAware es una interfaz especial de devolución de llamada para componentes que esperan recibir una referencia a ResourceLoader:
public interface ResourceLoaderAware {
void setResourceLoader(ResourceLoader resourceLoader);
}
Cuando una clase implementa ResourceLoaderAware y se despliega como bean gestionado por Spring, el contexto de aplicación la reconoce y llama a setResourceLoader(ResourceLoader), proporcionándose a sí mismo como argumento. Todos los contextos de aplicación de Spring implementan ResourceLoader.
Como ApplicationContext es un ResourceLoader, el bean también podría implementar ApplicationContextAware y utilizar directamente el contexto recibido para cargar recursos. Sin embargo, si solo necesitas cargar recursos, es preferible depender de la interfaz especializada ResourceLoader, porque el acoplamiento se limita a esa interfaz utilitaria y no a toda la interfaz ApplicationContext.
En componentes de aplicación también puedes autoconectar ResourceLoader en vez de implementar ResourceLoaderAware. Los modos tradicionales constructor y byType pueden proporcionar un ResourceLoader en un argumento de constructor o en un parámetro de método setter.
Para disponer de más flexibilidad —incluida la autoconexión de campos y métodos con varios parámetros—, utiliza las funciones de autoconexión basadas en anotaciones. En ese caso, se autoconecta un ResourceLoader en un campo, argumento de constructor o parámetro de método que espere ese tipo, siempre que el elemento esté anotado con @Autowired.
Para cargar uno o varios Resource a partir de una ruta que contiene comodines o utiliza el prefijo especial classpath*:, considera autoconectar ResourcePatternResolver en lugar de ResourceLoader.
Recursos como dependencias
Si el propio bean determina y proporciona dinámicamente la ruta de recursos, normalmente tiene sentido que utilice ResourceLoader o ResourcePatternResolver. Por ejemplo, al cargar una plantilla cuya ubicación concreta depende del rol de la persona usuaria.
Si los recursos son estáticos, puedes prescindir de ResourceLoader y ResourcePatternResolver: expón las propiedades Resource que necesita el bean y deja que se inyecten.
Todos los contextos de aplicación registran y utilizan un PropertyEditor especial de JavaBeans que convierte rutas String en objetos Resource. Por ejemplo, la siguiente clase MyBean tiene una propiedad template de tipo Resource:
public class MyBean {
private Resource template;
public void setTemplate(Resource template) {
this.template = template;
}
// ...
}
En XML, puedes configurar template con una cadena simple que represente el recurso:
<bean id="myBean" class="example.MyBean">
<property name="template" value="some/resource/path/myTemplate.txt"/>
</bean>
La ruta no tiene prefijo. Por tanto, dado que el propio contexto de aplicación se utiliza como ResourceLoader, el recurso se carga como ClassPathResource, FileSystemResource o ServletContextResource, según el tipo exacto de ApplicationContext.
Para forzar un tipo de Resource, utiliza un prefijo:
<property name="template"
value="classpath:some/resource/path/myTemplate.txt"/>
<property name="template"
value="file:///some/resource/path/myTemplate.txt"/>
Si MyBean se adapta a una configuración basada en anotaciones, puedes guardar la ruta en una clave llamada template.path, por ejemplo, en un archivo de propiedades disponible en el Environment de Spring. Después, puedes hacer referencia a ella mediante @Value y un marcador de posición.
Spring obtiene el valor de la ruta como String y un PropertyEditor especial lo convierte en un objeto Resource para inyectarlo en el constructor de MyBean:
@Component
public class MyBean {
private final Resource template;
public MyBean(@Value("${template.path}") Resource template) {
this.template = template;
}
// ...
}
Para admitir varias plantillas encontradas en una misma ruta y en varias ubicaciones del classpath —por ejemplo, en distintos JAR—, utiliza classpath*: y comodines. Por ejemplo, define templates.path como classpath*:/config/templates/*.txt.
Spring convierte el patrón en un array de Resource que se puede inyectar en el constructor:
@Component
public class MyBean {
private final Resource[] templates;
public MyBean(@Value("${templates.path}") Resource[] templates) {
this.templates = templates;
}
// ...
}
Contextos de aplicación y rutas de recursos
Esta sección explica cómo crear contextos de aplicación con recursos, los atajos que funcionan con XML, el uso de comodines y otros detalles.
Crear contextos de aplicación
El constructor de un contexto de aplicación —para un tipo concreto de ApplicationContext— suele recibir una cadena o un array de cadenas como rutas de ubicación de recursos, por ejemplo, archivos XML que constituyen la definición del contexto.
Cuando una ruta no tiene prefijo, el tipo concreto de Resource creado a partir de ella para cargar las definiciones de beans depende del contexto de aplicación concreto.
Por ejemplo, el siguiente código crea un ClassPathXmlApplicationContext:
ApplicationContext ctx =
new ClassPathXmlApplicationContext("conf/appContext.xml");
Las definiciones de beans se cargan desde el classpath porque se utiliza ClassPathResource.
En cambio, el siguiente código crea un FileSystemXmlApplicationContext:
ApplicationContext ctx =
new FileSystemXmlApplicationContext("conf/appContext.xml");
Las definiciones de beans se cargan desde el sistema de archivos, en este caso de forma relativa al directorio de trabajo actual.
El prefijo especial classpath: o un prefijo URL estándar en la ruta de ubicación sustituye el tipo predeterminado de Resource utilizado para cargar las definiciones de beans:
ApplicationContext ctx =
new FileSystemXmlApplicationContext("classpath:conf/appContext.xml");
Aunque FileSystemXmlApplicationContext carga las definiciones desde el classpath, sigue siendo un FileSystemXmlApplicationContext. Por tanto, si se utiliza después como ResourceLoader, las rutas sin prefijo continúan tratándose como rutas del sistema de archivos.
Atajos para crear ClassPathXmlApplicationContext
ClassPathXmlApplicationContext ofrece varios constructores para una instanciación práctica. Puedes proporcionar solo un array con los nombres de los archivos XML —sin información de ruta inicial— y una Class. A partir de ella, ClassPathXmlApplicationContext deduce la ruta.
Considera esta estructura:
com/
example/
services.xml
repositories.xml
MessengerService.class
Puedes crear un ClassPathXmlApplicationContext compuesto por los beans definidos en services.xml y repositories.xml así:
ApplicationContext ctx = new ClassPathXmlApplicationContext(
new String[] {"services.xml", "repositories.xml"},
MessengerService.class);
Consulta el Javadoc de ClassPathXmlApplicationContext para conocer las distintas variantes de constructores.
Comodines en rutas de recursos de constructores de contextos
Las rutas de recursos que se pasan a constructores de contextos pueden ser rutas simples, cada una con correspondencia uno a uno con un Resource, o contener el prefijo especial classpath*: o patrones internos de estilo Ant, comparados mediante PathMatcher. Los dos últimos casos actúan como comodines.
Un caso de uso consiste en ensamblar aplicaciones por componentes. Cada componente puede publicar fragmentos de definición de contexto en una ruta conocida y, al crear el contexto final usando la misma ruta precedida por classpath*:, se recogen automáticamente todos los fragmentos.
El uso de comodines se limita a las rutas de recursos empleadas en constructores de contextos de aplicación —o cuando utilizas directamente la jerarquía de utilidades PathMatcher—. Se resuelven durante la construcción y no forman parte del tipo Resource. No puedes utilizar classpath*: para crear un Resource individual, porque un recurso representa una sola ubicación.
Patrones de estilo Ant
Las rutas pueden contener patrones de estilo Ant:
/WEB-INF/*-context.xml
com/mycompany/**/applicationContext.xml
file:C:/some/path/*-context.xml
classpath:com/mycompany/**/applicationContext.xml
Cuando una ruta contiene un patrón Ant, el resolvedor sigue un proceso más complejo: crea un Resource hasta el último segmento sin comodines y obtiene su URL. Si no es una URL jar: —ni una variante específica de contenedor, como zip: en WebLogic o wsjar en WebSphere—, obtiene un java.io.File y recorre el sistema de archivos para resolver los comodines.
En el caso de una URL de JAR, el resolvedor obtiene una java.net.JarURLConnection o analiza manualmente la URL del JAR para recorrer su contenido y resolver los comodines.
Implicaciones de portabilidad
Si la ruta especificada ya es una URL file —implícitamente, porque el ResourceLoader base es del sistema de archivos, o explícitamente—, el uso de comodines funciona de forma totalmente portable.
Si la ruta es una ubicación classpath, el resolvedor debe obtener la URL del último segmento de ruta sin comodines mediante ClassLoader.getResource(). Dado que ese segmento es un nodo de ruta y no el archivo final, el Javadoc de ClassLoader no define exactamente qué tipo de URL se devuelve.
En la práctica, suele ser un java.io.File que representa el directorio cuando el recurso del classpath resuelve a una ubicación de sistema de archivos, o una URL de JAR cuando resuelve a una ubicación dentro de JAR. Aun así, existe una cuestión de portabilidad.
Si se obtiene una URL de JAR para el último segmento sin comodines, el resolvedor debe poder obtener una JarURLConnection o analizar la URL para recorrer el JAR y resolver el comodín. Esto funciona en la mayoría de entornos, pero puede fallar en otros. Prueba exhaustivamente la resolución de comodines procedentes de JAR en tu entorno concreto antes de depender de ella.
El prefijo classpath*:
Al construir un contexto de aplicación basado en XML, puedes utilizar el prefijo especial classpath*::
ApplicationContext ctx =
new ClassPathXmlApplicationContext("classpath*:conf/appContext.xml");
Este prefijo indica que deben obtenerse todos los recursos del classpath que coincidan con el nombre indicado —internamente, de forma similar a una llamada a ClassLoader.getResources(…)— y combinarse para formar la definición final del contexto de aplicación.
El classpath con comodines depende de getResources() del ClassLoader subyacente. Como la mayoría de servidores de aplicaciones proporcionan su propia implementación de ClassLoader, el comportamiento puede variar, en especial con archivos JAR.
Una prueba sencilla consiste en utilizar el ClassLoader para cargar un archivo dentro de un JAR del classpath mediante getClass().getClassLoader().getResources("<archivoDentroDelJar>").
Prueba con archivos del mismo nombre ubicados en dos rutas diferentes, por ejemplo en dos JAR distintos del classpath. Si obtienes resultados inadecuados, consulta la documentación del servidor de aplicaciones para buscar configuraciones que puedan afectar al comportamiento de ClassLoader.
También puedes combinar classpath*: con un patrón PathMatcher en el resto de la ruta, por ejemplo classpath*:META-INF/*-beans.xml. En este caso, se llama a ClassLoader.getResources() sobre el último segmento sin comodines para encontrar todos los recursos coincidentes en la jerarquía del cargador de clases. A partir de cada recurso se aplica la estrategia PathMatcher para la subruta con comodines.
Otras notas sobre comodines
Cuando classpath*: se combina con patrones de estilo Ant, solo funciona de forma fiable si hay al menos un directorio raíz antes de que empiece el patrón, salvo que los archivos de destino residan realmente en el sistema de archivos.
Por tanto, un patrón como classpath*:*.xml puede no recuperar archivos situados en la raíz de los JAR, sino solo en la raíz de directorios expandidos.
La capacidad de Spring para recuperar entradas del classpath procede de ClassLoader.getResources() del JDK, que solo devuelve ubicaciones de sistema de archivos para una cadena vacía, es decir, posibles raíces de búsqueda. Spring también evalúa la configuración en tiempo de ejecución de URLClassLoader y el manifiesto java.class.path de los JAR, pero esto no garantiza un comportamiento portable.
La exploración de paquetes del classpath requiere las entradas de directorio correspondientes. Al crear JAR con Ant, no actives la opción files-only de la tarea JAR. Además, en algunos entornos, las políticas de seguridad pueden impedir que se expongan directorios del classpath.
En la ruta de módulos del sistema de módulos de Java, la exploración del classpath de Spring suele funcionar como se espera. Aun así, es recomendable colocar los recursos en un directorio dedicado para evitar los problemas de portabilidad asociados a buscar en la raíz de los JAR.
Los patrones Ant con recursos classpath: no garantizan encontrar los recursos coincidentes si el paquete raíz de búsqueda está disponible en varias ubicaciones del classpath.
Por ejemplo, considera el recurso:
com/mycompany/package1/service-context.xml
Y el patrón:
classpath:com/mycompany/**/service-context.xml
El recurso puede existir en una única ubicación del classpath. Sin embargo, el resolvedor trabaja a partir de la primera URL devuelta por getResource("com/mycompany"). Si ese nodo de paquete base existe en varias ubicaciones de ClassLoader, es posible que el recurso deseado no esté en la primera ubicación encontrada.
En esos casos, prefiere classpath*: con el mismo patrón, que busca en todas las ubicaciones del classpath que contienen el paquete base com.mycompany:
classpath*:com/mycompany/**/service-context.xml
Consideraciones sobre FileSystemResource
Un FileSystemResource que no esté asociado a un FileSystemApplicationContext —es decir, cuando dicho contexto no sea el ResourceLoader real— trata las rutas absolutas y relativas como cabría esperar. Las rutas relativas se interpretan respecto al directorio de trabajo actual y las absolutas respecto a la raíz del sistema de archivos.
Por motivos históricos y de compatibilidad, esto cambia cuando FileSystemApplicationContext es el ResourceLoader. Este contexto fuerza que todos los FileSystemResource asociados traten todas las rutas como relativas, tengan o no una barra inicial.
En la práctica, estos ejemplos son equivalentes:
ApplicationContext ctx =
new FileSystemXmlApplicationContext("conf/context.xml");
ApplicationContext ctx =
new FileSystemXmlApplicationContext("/conf/context.xml");
También son equivalentes los siguientes ejemplos, aunque uno parezca relativo y el otro absoluto:
FileSystemXmlApplicationContext ctx = ...;
ctx.getResource("some/resource/path/myTemplate.txt");
FileSystemXmlApplicationContext ctx = ...;
ctx.getResource("/some/resource/path/myTemplate.txt");
Cuando necesites rutas absolutas reales del sistema de archivos, evita utilizar rutas absolutas con FileSystemResource o FileSystemXmlApplicationContext. Fuerza el uso de UrlResource con el prefijo URL file::
// El tipo de contexto no importa: el Resource siempre será UrlResource.
ctx.getResource("file:///some/resource/path/myTemplate.txt");
// Fuerza a este FileSystemXmlApplicationContext a cargar su definición mediante UrlResource.
ApplicationContext ctx =
new FileSystemXmlApplicationContext("file:///conf/context.xml");