Trabajo relacionado con Java

29 de Junio de 2007

Gestión de la auditoría con Spring 2.0

Archivado en: Desarrollo — jansoblog @ 9:22 am
Tags: , ,

Spring 2.0 introduce dos nuevos scope para quienes desarrollamos aplicaciones web.
Esta nueva funcionalidad simplifica un trabajo tan arduo como la gestión de auditoría.

Para que el ejemplo quede más claro, como gestión de auditoría vamos a enteder que se indique en el log qué usuario ha realizado una determinada acción.

Realizar esta tarea sin Spring, consistiría principalmente en pasar un nuevo argumento a cada uno de los métodos de la lógica de negocio inidicando el usuario.

Existen otras formas que no voy a discutir, como poner la información en ThreadLocal.

A continuación, indicaré los pasos para crear un bean de sessión en Spring y hacer que un servicio singleton lo reciba, y de esta manera pueda hacer log del usuario y la acción.

Configurar web.xml (fragmento)

<listener> 
<listener-class>
  org.springframework.web.context.request.RequestContextListener
  </listener-class>
 </listener>
 <listener>
  <listener-class>
  org.springframework.web.context.ContextLoaderListener
  </listener-class>
 </listener>

Crear el bean con la información del usuario

package sadiel.rrhhsas.model.comun.objnegocio;
public class UsuarioSession implements Serializable, IUsuario {
String usuario; // Código del usuario
 // getters y setters
  // ..
}

Crear el servicio


package sadiel.rrhhsas.model.adm.usu.service.impl;
public class UsuarioServiceImpl implements IUsuarioService {
IUsuario usuario; //Usuario de session
// the logger for this class
private Log logger = LogFactory.getLog(this.getClass());
/**
  * Valida a un usuario a partir de su usuario y su clave.
  * Introduce el usuario en la session para que sea accesible por otros servicios
  * @param clogin
  * el usuario que usamos
  * @param cclave
  * la clave que usamos
  * @return true
  */
 public boolean login(String clogin, String cclave)
  throws UsernameNotExistException {
// Valido al usuario
  // ...
  // Informo en el usuario de sessión el código del usuario conectado
  usuario.setUsuario(user.getCUsuario());
return true;
}
/**
* @see IUsuarioService#actualizar(Object o)
*/
public void actualizar(Object o) {
this.logger.debug("El usuario "+usuario.getCUsuario() +
" modifica el objeto "+o);

// Resto del servicio
// ..
}
/**
* Set the user in session
* It will be used by the Spring IOC container.
* @param usuario the usuario to set
*/
public void setUsuario(IUsuario usuario) {
this.usuario = usuario;
}
}

Configurar applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
<bean id="Usuario"
  class="sadiel.rrhhsas.model.comun.objnegocio.UsuarioSession"
  scope="session">
  <aop:scoped-proxy/> <!-- Esto hay que incluirlo en los beans
  con scope="session" si los queremos
  utilizar en otros bean singleton -->
 </bean>
<bean id="iUsuarioService"
  class="sadiel.rrhhsas.model.adm.usu.service.impl.UsuarioServiceImpl" >
  <property name="usuario">
  <ref bean="Usuario" />
  </property>
 </bean>
</beans>Por supuesto si quisieramos que todos los servicios recibieran al usuario, lo que habría que hacer es definir un servicio abstracto y hacer que todos los servicios fueran hijos de este, pero de eso bloquearé otro día.Y eso es todo, algún comentario sería apreciado.

26 de Junio de 2007

Ejemplo del sistema de acceso a los recursos en Spring 2.0

Archivado en: Desarrollo — jansoblog @ 9:21 am
Tags: , ,

En este ejemplo nos vamos a concentrar en la configuración del SessionFactory de Hibernate y las diferentes alternativas que nos ofrece el sistema de abstracción de recursos para simplificar la configuración y mantener distintas configuraciones.

A continuación veamos una configuración básica del sessionFactory de Spring para Hibernate con conexión a Oracle.

<bean id=“sessionFactory”

      class=“org.springframework.orm.hibernate3.LocalSessionFactoryBean”>

      <property name=“dataSource”>

            <ref bean=“dataSource” />

      </property>

      <property name=“hibernateProperties”>

            <props>

             <prop key=“hibernate.dialect”> org.hibernate.dialect.Oracle9Dialect

             </prop>

             <prop key=“hibernate.show_sql”> false</prop>

             <prop key=“hibernate.cglib.use_reflection_optimizer”> true

             </prop>

            </props>

      </property>

      <property name=“mappingResources”>

           <list>           <value>sadiel/rrhhsas/model/adm/usu/objnegocio/Perfil.hbm.xml</value>               <value>sadiel/rrhhsas/model/adm/usu/objnegocio/Usuario.hbm.xml</value>                 <value>sadiel/rrhhsas/model/adm/usu/objnegocio/UsuarioPerfil.hbm.xml</value>

            </list>

      </property>

</bean>

El primer problema que podemos ver es que la lista de mappingResources va a crecer continuamente y se hará muy extensa. Cualquiera ha trabajado en un proyecto con 100 tablas o más.

Afortunadamente LocalSessionFactoryBean tiene otra propiedades de tipo Resource[] que no va a permitir solucionar este problema. Y la configuración quedaría de este modo.

      <property name=“mappingLocations”>

            <!– Cargamos todos los ficheros hibernate que haya en el classpath dentro del paquete –>

            <value>classpath:sadiel/**/*.hbm.xml</value>

      </property>

Quizás más sutil, pero tampoco parece coherente tener una configuración compleja como la configuración de hibernate, dentro de la configuración de la aplicación. Sobretodo pensando que podemos tener distintas configuraciones para entornos diferentes, o para clientes diferentes.

En este caso LocalSessionFactoryBean no nos puede ayudar directamente ya que no tiene una propiedad de tipo Resource para configurar las propiedades de hibernate. Sin embargo si que podemos hacer referencia a otro bean que contenga estas propiedades.

<bean id=“sessionFactory”

      class=“org.springframework.orm.hibernate3.LocalSessionFactoryBean”>

      <property name=“dataSource”>

            <ref bean=“dataSource” />

      </property>

            <property name=“hibernateProperties”>

                  <ref bean=“hibernateProperties” />

            </property>

      <property name=“mappingLocations”>

            <value>classpath:sadiel/**/*.hbm.xml</value>

      </property>

</bean>

<bean id=“hibernateProperties”

      class=“sadiel.rrhhsas.model.comun.util.ResourcePropertiesUtil”>

      <property name=“propertiesLocations”>

            <value>classpath:hibernate.properties</value>

      </property>

</bean>

De esta manera volvemos a usar el tradicional archivo de configuración hibernate.properties.

La implementación de ResourcePropertiesUtil es muy sencilla, pero la incluyo por completitud.          

package sadiel.rrhhsas.model.comun.util;

public class ResourcePropertiesUtil extends Properties {

       private Resource[] propertiesLocations;

      

       public void setPropertiesLocations(Resource[] propertiesLocations) throws IOException  {

             this.propertiesLocations = propertiesLocations;

             for (Resource resource : propertiesLocations) {

                           super.load(resource.getInputStream());

             }

       }

}

Suponiendo que tenemos que mantener diversas configuraciones, podríamos definir el bean con diferentes propiedades y obtener una de ellas según otro parámetro de configuración. 

Existen otras propiedades que pueden aprovechar esta aproximación de la configuración. Trabajando con Spring 1.1 sólo era posible definir la caché de segundo nivel de Hibernate en cada uno de los fichero hbm. Pero desde la versión de Spring 1.2 es posible informar la caché de clases en la propiedad entityCacheStrategies y la caché de colecciones en la propiedad collectionCacheStrategies, ambas de tipo Properties.  

Dejo el resto a vuestra imaginación. 

Referencias

http://www.springframework.org/docs/reference/resources.html

Blog de WordPress.com.