lunes, 28 de marzo de 2011

Definición y obtención de servicios con Spring

Una de las múltiples características del framework Spring es la inyección de dependencias. Mediante la misma, podemos definir los beans que implementan la lógica de nuestras aplicaciones. De esta forma nos podemos olvidar de la gestión de los mismos puesto que Spring lo hará por nosotros.

Hay varias formas de definir nuestros beans:


  • Directamente los definimos en nuestro fichero de contexto de Spring (applicationContext.xml) mediante etiquetas <bean>. En la definición del mismo podemos asignarle al mismo otros beans  que hayamos definido o propiedades (tanto simples como complejas como listas o maps).




  • También podemos definirlos mediante anotaciones del tipo @Service("nombreServicio") en la propia clase de nuestro servicio. Lo único que deberemos añadir a nuestro fichero de contexto son las siguientes entradas para indicar a Spring en qué paquete encontrar las clases que contienen anotaciones.
    


















Nuestra clase tendría un aspecto parecido al siguiente:


package es.jpascu.app.service;

import org.springframework.stereotype.Service;

@Service("miServicio")

public class MiServicio {
...
}

Una vez que hemos definidos nuestros beans debemos obtenerlos para ejecutarlos desde nuestra aplicación web. Hay diferentes formas de obtener los servicios dependiendo de donde queramos obtenerlos dentro de nuestra aplicación web:


  • Acceso genérico desde una aplicación Web.
WebApplicationContext springCtx = WebApplicationContextUtils.getRequiredWebApplicationContext(ServletActionContext.getServletContext() );
ClaseDeBean miBean = ( ClaseDeBean )springCtx.getBean( "idDelBean" );
  • Acceso desde un servlet. Primero debemos definir el servlet en nuestro applicationContext.xml e inyectarle los beans a los que queramos acceder desde el mismo.









Una vez hecho esto el bean se obtendrá de la siguiente forma:

SolicitudService sService = ( SolicitudService) request.getSession().getServletContext().getAttribute( "solicitudService" );

  • Acceso desde un Job de Quartz. 
protected static final String APPLICATION_CONTEXT_KEY = "applicationContext";
ApplicationContext springCtx = ApplicationContext)context.getScheduler().getContext().get(APPLICATION_CONTEXT_KEY);
ClaseDeBean miBean = ( ClaseDeBean )springCtx.getBean( "idDelBean" );
  • Acceso desde un contexto personalizado. Personalmente utilizo está forma cuando necesito acceder a un bean del contexto desde una simple clase Java, siendo esta clase la implementación de un Web Service. Lo primero que hago es crear una clase que representa mi contexto y que implementa la interfaz ApplicationContextAware. 
  • package es.jpascu.app.utils;
     import org.apache.log4j.Logger;
    import org.springframework.beans.BeansException;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.ApplicationContextAware;
    
    /**
    * Wrapper to always return a reference to the Spring Application Context from
    * within non-Spring enabled beans. Unlike Spring MVC's WebApplicationContextUtils
    * we do not need a reference to the Servlet context for this. All we need is
    * for this bean to be initialized during application startup.
    */
    
    public class SpringApplicationContext implements ApplicationContextAware {
    
    private static ApplicationContext CONTEXT;
    private static Logger logger = Logger.getLogger(SpringApplicationContext.class);
    
    /**
    * This method is called from within the ApplicationContext once it is 
    * done starting up, it will stick a reference to itself into this bean.
    * @param context a reference to the ApplicationContext.
    */
    public void setApplicationContext(ApplicationContext context) throws BeansException {
    logger.info("SetApplicationContext " + context);
    CONTEXT = context;
    }
    /**
    * This is about the same as context.getBean("beanName"), except it has its
    * own static handle to the Spring context, so calling this method statically
    * will give access to the beans by name in the Spring application context.
    * As in the context.getBean("beanName") call, the caller must cast to the
    * appropriate target class. If the bean does not exist, then a Runtime error
    * will be thrown.
    * @param beanName the name of the bean to get.
    * @return an Object reference to the named bean.
    */
    public static Object getBean(String beanName) {
    return CONTEXT.getBean(beanName);
    }
    }
    


       Después definiremos este bean en nuestro fichero applicationContext.xml:


        Por último, obtenemos nuestro bean de la siguiente forma:



SpringApplicationContext.getBean("miServicio");




  • Acceso desde una pantalla Flex. También se puede invocar un servicio de Spring desde una pantalla de Flex, puesto que hay varios productos que integran Flex con Java. Algunos son de pago (Exadel Flamingo) y otros son gratuitos (BlazeDS). Primero lo definimos como un objeto remoto indicando sus métodos:




  


         Posteriomente lo podemos utilizar desde nuestro código en Action Script:

         

MiServicio.ejecutar();

2 comentarios:

  1. Siento corregirte pero Exadel Flamingo no es de pago, ya que forma parte de Exadel Community and Open Source Projects. http://exadel.org/

    ResponderEliminar
  2. Gracias, me ayudo mucho el SpringApplicationContext!

    ResponderEliminar