La Coctelera

foo-bar

Un blog sobre esto y lo otro

14 Abril 2008

Acceso al contexto de Spring mediante código

Cuando se usa Spring, normalmente no hay que preocuparse de lo que hay por detrás de la inyección de dependencias: se obtienen los beans indicados en los ficheros de configuración por "arte de magia". Sin embargo, hay situaciones en las que es necesario acceder a dichos beans y la inyección de dependencias no es automática o, dicho de otro modo, hay que acceder manualmente al contexto de Spring para tener acceso a los beans.

A continuación, el listado de todos los casos en que esta situación puede darse (si hay alguno más o hay algo incorrecto, por favor deja un comentario, que yo solo escribo un blog O:-)):

1.- Acceso genérico en una aplicación web.
Aunque en la mayoría de los casos la inyección de dependencias se realiza configurando referencias en los archivos de Spring (los típicos ficheros applicationContext*.xml), puede que en alguna ocasión especial se necesite acceder directamente al contexto para obtener un bean por programación. Esto se haría así:

WebApplicationContext springCtx =
    WebApplicationContextUtils.getRequiredWebApplicationContext(
        ServletActionContext.getServletContext()
    );
ClaseDeBean miBean = ( ClaseDeBean )springCtx.getBean( "idDelBean" );

2.- Acceso desde un servlet.
Para acceder al contexto de Spring desde un Servlet, hay que definir un bean en el applicationContext*.xml de turno tal que:

<bean class="org.springframework.web.context.support.ServletContextAttributeExporter">
  <property name="attributes">
    <map>
      <!-- inyecta los siguientes beans en el servlet context para que los servlets puedan acceder a ellos -->
      <entry key="projectManager" value-ref="projectManager" />
      <entry key="userManager" value-ref="userManager" />
    </map>
  </property>
</bean>

De este modo, los beans indicados en el map estarán disponibles en los servlets como si fueran un atributo más del ServletContext:

ProjectManager projectManager = ( ProjectManager )request.getSession().getServletContext().getAttribute( "projectManager" );

3.- Acceso desde un Custom Tag.
Se debe heredar de la clase org.springframework.web.servlet.tags.RequestContextAwareTag, que a su vez hereda de TagSupport. Los beans se declaran en la clase, como se hace en Spring normalmente, declarando los objetos de turno con sus getter y setter. El método "equivalente" a doStartTag() es doStartTagInternal(), dónde se debe implementar la lógica del Custom Tag. Se obtienen los beans de Spring sin necesidad de configuraciones adicionales:

WebApplicationContext springCtx = getRequestContext().getWebApplicationContext();
userManager = ( UserManager )springCtx.getBean( "userManager" );

4.- Acceso en los tests unitarios (JUnit).
Para acceder al contexto de Spring en los tests unitarios, la clase con los mismos debe heredar de -respira hondo que va la clase- org.springframework.test.AbstractTransactionalDataSourceSpringContextTests.

Esta clase funciona como cualquier otra clase de JUnit, en la que adicionalmente hay que implementar el método protected String[] getConfigLocations(), que debe devolver un String[] con las localizaciones de los ficheros dónde están definidos los beans de Spring que se quieren inyectar en los tests. Además, se debe indicar el modo de inyección (autowire) de los beans. Un ejemplo de dicho método sería:

protected String[] getConfigLocations() {
  setAutowireMode(AUTOWIRE_BY_NAME);
  return new String[] {
      "classpath:/applicationContext-resources.xml",
      "classpath:/applicationContext-dao.xml",
      "classpath*:/applicationContext.xml",
      "classpath:**/applicationContext*.xml"
  };
}

El uso de comodines aplica exactamente igual que cuándo se definen en el fichero web.xml.

5.- Acceso genérico en una aplicación stand-alone.
Por último, para acceder al contexto de Spring desde una clase de una aplicación de escritorio:

ClassPathXmlApplicationContext springCtx =
  new ClassPathXmlApplicationContext( new String[] {
      "classpath:/applicationContext-resources.xml",
      "classpath:/applicationContext-dao.xml",
      "classpath*:/applicationContext.xml" });
UserManager userManager = ( UserManager )springCtx.getBean( "userManager" );

En el array de String se pueden incluir comodines como de costumbre, solamente hay que tener en cuenta que los ficheros de configuración de los beans tienen que estar cargados en el classpath de la aplicación.

El Capitán Obvio advierte: hay que tener en cuenta que instanciar un ClassPathXmlApplicationContext es costoso, dado que carga todos los beans definidos en los ficheros xml, por lo que el procedimiento normal a seguir es instanciarlo cuando arranque la aplicación, por ejemplo en un Singleton, y luego obtener los beans a través de dicho objeto.

servido por foobar sin comentarios compártelo

sin comentarios · Escribe aquí tu comentario

Escribe tu comentario


Sobre mí

    Como se puede observar en esta foto, visto chistera, tengo monóculo, fumo puros y, probablemente, bebo cerveza.

    Para regalarme jamones, ofrecerme dinero o simplemente mandarme unas líneas, nada como usar el formulario de contacto.

Tag de sabiduría

Estadísticas


    Ver las estadísticas de foo-bar

    spam posion

Fotos

foobar todavía no ha subido ninguna foto.

¡Anímale a hacerlo!

Buscar

suscríbete

Selecciona el agregador que utilices para suscribirte a este blog (también puedes obtener la URL de los feeds):

¿Qué es esto?

Crea tu blog gratis en La Coctelera