Mostrando entradas con la etiqueta AOP. Mostrar todas las entradas
Mostrando entradas con la etiqueta AOP. Mostrar todas las entradas

martes, 3 de julio de 2007

Recargar factoria de elementos al acabar una conversación

Para recargar una factoría de objetos que tendremos cargados en session para optimizar el rendimiento de la base de datos, podemos utilizar los eventos, los cuales al finalizar una tarea/conversación se pueden encargar de forma transparente (programación orientada a aspectos) de acceder a variables de otros componentes para su inicialización.
Ejemplo:
al finalizar un pedido de compra se necesita que el catalogo de productos muestre el stock actualizado.

public class CheckOutBean implements CheckOut, Serializable{
...
@End
@RaiseEvent("limpiarCatalogo")
public void enviarPedido() {
persist.order()

}
}

public class CatalogoBean implements Serializable, Catalogo {
...

@Observer("limpiarCatalogo")
public void limpiarPiezas(){
log.error("RESET CATALOGO ");
piezasList=null;

}
}


**** Esto puede parecer obvio, pero si lo que hacemos es recargar la colección en vex de limpiarla no funcionará, ya que la transacción depende de las phases de jsf, es decir que no se producirá la actualización hasta que no se salga de la PhaseId.INVOKE_APPLICATION.

jueves, 28 de junio de 2007

Interceptar toda la aplicacion en Seam

Podemos utilzar la filosofía de Seam de interceptar todo, para cronometrar nuestra aplicación y comprobar en que métodos se producen retardos.

  1. Creamos una clase que extienda de org.jboss.seam.ejb.SeamInterceptor es decir la clase que utiliza Seam para interceptar los componentes de la aplicacion:
    • public class MiaoInterceptor extends SeamInterceptor {

      @AroundInvoke
      public Object aroundInvoke(InvocationContext invocation) throws Exception
      {

      if(invocation.getTarget().getClass().getPackage().toString().contains("es.miao")){
      long l = System.currentTimeMillis();

      String invocacion=invocation.getTarget().getClass().getSimpleName()+"."+invocation.getMethod().getName()+"()";
      System.out.println("INICIANDO: "+invocacion);

      Object o = invocation.proceed();
      long ll = System.currentTimeMillis();

      System.out.println("FINALIZANDO: "+invocacion+" Tiempo total: "+(ll-l)+" milisegundos");

      return o;
      }
      return invocation.proceed();
      }

      }
  2. Cambiar en el ejb-jar.xml el interceptor de seam por el nuestro
    • <?xml version="1.0" encoding="UTF-8"?>
      <ejb-jar xmlns="http://java.sun.com/xml/ns/javaee"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd"
      version="3.0">
      <interceptors>
      <interceptor>
      <interceptor-class>org.jboss.seam.ejb.SeamInterceptor</interceptor-class>
      </interceptor>
      <interceptor>
      <interceptor-class>es.miao.MiaoInterceptor</interceptor-class>
      </interceptor>
      </interceptors>
      <assembly-descriptor>
      <interceptor-binding>
      <ejb-name>*</ejb-name>
      <interceptor-class>org.jboss.seam.ejb.SeamInterceptor</interceptor-class>
      </interceptor-binding>
      <interceptor-binding>
      <ejb-name>*</ejb-name>
      <interceptor-class>es.miao.MiaoInterceptor</interceptor-class>
      </interceptor-binding>
      </assembly-descriptor>
      </ejb-jar>

martes, 26 de junio de 2007

(Interceptores)Factorias de session que se recargan según eventos:

De esta forma no recargamos las llamadas a la base de datos:

@Stateful
@Scope(SESSION)
@Name("bookingList")
@Restrict("#{identity.loggedIn}")
@TransactionAttribute(REQUIRES_NEW)
public class BookingListAction implements BookingList, Serializable
{
.......

@Factory
@Observer("bookingConfirmed")
public void getBookings()
{
bookings = em.createQuery("select b from Booking b where b.user.username = :username order by b.checkinDate")
.setParameter("username", user.getUsername())
.getResultList();
}
........
}
@Stateful
@Name("hotelBooking")
@Restrict("#{identity.loggedIn}")
public class HotelBookingAction implements HotelBooking
{
...

@End
public void confirm()
{
em.persist(booking);
facesMessages.add("#{messages.gracias}, #{user.name}, your confimation number for #{hotel.name} is #{booking.id}");
log.info("New booking: #{booking.id} for #{user.username}");
events.raiseTransactionSuccessEvent("bookingConfirmed");
}
...
}

miércoles, 11 de abril de 2007

¿qué es un Aspecto en una instancia de clase u objeto?

¿qué es un aspecto en la programación orientada a aspectos POA?

Un aspecto es una serie de operaciones que se repiten y pueden afectar a diferentes objetos y operaciones diferentes.
Un caso común es la métrica o testeo de la aplicación en tiempo. Si tenemos que incluir el código relacionado con medir el tiempo que tarda un método en ejecutarse dentro del propio método, entonces estamos mezclando aspectos diferentes e independientes del programa, tales como la ejecucion de una suma y el tiempo que tarda el producirse.



**** en desarrollo pero se refiere al aspecto en su forma más abstracta o dicho de otra forma el aspecto como perteneciente a un proceso

  1. El aspecto se puede referir al estado temporal (entendido como fase temporal o estado) del ciclo de vida de un objeto.
  2. También se puede entender como un comportamiento (interfaz) de la clase o instancia.

Los aspectos se implementan en forma de interceptores.
Un interceptor es un proxy.
En un programa orientado a aspectos debe existir un objeto que se encarga de devolver las nuevas instancias de las clases implicadas en la ejecución del programa. Este objeto encargado de la creación de nuevos objetos (el típico SpringFrameWork o Jboss Seam) devuelve proxys que tiene el mismo comportamiento que la clase esperada pero además aporta más comportamientos a la clase.


Ideas a desarrollar:
Entender la programación como un algoritmo de ciclos temporales/vitales de la instancia de un objeto.

Could not find selected item matching value af:selectOneChoice f:selectItems

Este problema se da cuando en un selecItems no encuentra en la lista de posibles valores el valor seleccionado (selected) aunque veamos que de hecho si existe.

ADF/JSF al intentar seleccionar el valor de la lista de posibles valores lo hace a través del metodo equals() que tenemos que sobreescribir para que compare las claves de negocio y no compare por serialización del objeto (en este caso nunca serian iguales dos instancias con iguales valores de una clase).

Y el problema se produce cuando el acceso a los valores lo hacemos sin el correspondiente metodo interceptado por hibernate (PORQUE SI UTILIZAMOS HIBERNATE ESTAMOS UTILIZANDO POA [programación orientada a aspectos y por lo tanto interceptores] )
por un problema en la implementacion del equals e Hibernate.

La razón de este error es la siguiente:

Al acceder a las propiedades de los objetos sin el metodo adecuado (interceptado por hibernate) es decir los getter, el valor que devuelve es el que tiene por defecto la clase o el que tenga la instancia del objeto en un momento dado del programa.

martes, 27 de marzo de 2007

Interceptores Jboss Seam

Fases de JSF ya es mucha diferencia

Hay que crear una @interface que la utilizaremos para etiquetar/interceptar la clase(componente en terminos de Seam) correspondiente


import javax.interceptor.Interceptors;
import java.lang.annotation.Documented;
import static java.lang.annotation.ElementType.TYPE;
import java.lang.annotation.Retention;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Target;

/**
* Created by IntelliJ IDEA.
* User: juanitu
* Date: 12-abr-2007
* Time: 17:43:24
* To change this template use File | Settings | File Templates.
*/
@Target(TYPE)
@Retention(RUNTIME)
@Documented
@Interceptors(Interceptor.class)
public @interface EtiquetaInterceptora {

}


Despues definimos el interceptor poniendo especial interes en como tratamos el tema de las fases de la aplicacion:



import org.jboss.seam.annotations.Around;
import org.jboss.seam.annotations.Within;
import org.jboss.seam.interceptors.*;
import org.jboss.seam.contexts.Contexts;
import org.jboss.seam.contexts.Lifecycle;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import javax.interceptor.AroundInvoke;
import javax.interceptor.InvocationContext;
import javax.faces.event.PhaseId;

import es.cafs.dao.CafsDAO;
import es.cafs.metadata.componentes.Componentes;

import java.lang.reflect.Method;

/**
* Created by IntelliJ IDEA.
* User: juanitu
* Date: 12-abr-2007
* Time: 17:45:36
* To change this template use File | Settings | File Templates.
*/
@Around({BijectionInterceptor.class, ValidationInterceptor.class,
ConversationInterceptor.class, BusinessProcessInterceptor.class})
@Within(RemoveInterceptor.class)
public class Interceptor {

protected static Log log = LogFactory.getLog(org.jboss.seam.interceptors.Interceptor.class);

@AroundInvoke
public Object checkLoggedIn(InvocationContext invocation) throws Exception {

CafsDAO dao = (CafsDAO) Contexts.getApplicationContext().get(Componentes.appCafsDAO);
log.error(dao==null);

Method method = invocation.getMethod();
log.error(invocation.getTarget().getClass()+"-"+method.getName() + " " + method.getReturnType());
if (Lifecycle.getPhaseId() == PhaseId.INVOKE_APPLICATION) {
log.error("INVOCANDO FASE");
} else {
log.error(invocation.getTarget().getClass()+"-"+method.getName() + " " + method.getReturnType());
log.error("OTRA FASE");

}

return invocation.proceed();
}
}





Y por último hay que etiquetar el componente correspondiente


@Scope(ScopeType.CONVERSATION)
@Name(Componentes.convVisorInformacion)
@Logeando
public class VisorInformacion{
}