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í:
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:
<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:
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:
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:
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:
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.
Escribe un comentario
Los comentarios están cerrados