Monday, January 15, 2007

Portal, portlets y otras yerbas.

Buscando documentacion sobre Websphere Portal me tope con un articulo de IBM un poquito desactualizado. La nota comienza asi: "Ya sabemos que un portlet es un servlet...". En serio? No seria mejor decir "Un portlet ERA un servlet..". Antes de la JSR-168 (Portlet specification) un portlet era un servlet ya que la clase Portlet extendia a la clase Servlet. Desde la JSR-168 esto ya no es cierto, uno Portlet NO ES un Servlet. Si bien los conceptos son similares estaria bueno que los muchachos de IBM dejaran de publicar esas notas, salvo que, claro...las actualicen.

Wednesday, January 03, 2007

Midiendo tiempos...sin Annotations

Que pasa si no dispongo de Java 5.0 y no puedo hacer uso de las annotations? Bien, aca esta la solucion al ejemplo anterior pero sin anotaciones.
package com.miempresa.training.aop.advices;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class MiAOPTimer implements MethodInterceptor {
private static Log logger = LogFactory.getLog(MiAOPTimer.class);

public Object invoke(MethodInvocation methodInvocation) throws Throwable {
long t1 = System.currentTimeMillis();
Object retorno = methodInvocation.proceed();
long t2 = System.currentTimeMillis();
logger.info("Método:"+methodInvocation.getMethod().getName()+" ("+(t2-t1)+" ms)");
return retorno;
}
}

El primer cambio notorio es que ahora nuestro advice debe implementar una interfase y sobrescribir el metodo invoke, el resto del codigo queda igual.
Finalmente, nuestro archivo de configuracion de Spring queda de la siguiente forma:
<beans>
<aop:config>
<aop:advisor pointcut="execution(* com.miempresa.training..*.*(..))"
advice-ref="MiAOPTimer"/>
</aop:config>
<bean id="usuarioService" class=com.miempresa.training.aop.UsuarioServiceImpl"/>
<bean id="MiAOPTimer" class="com.miempresa.training.aop.advices.MiAOPTimer"/>
</beans>

Midiendo tiempos con Spring AOP

No hay nada mas facil que integrar AOP (Aspect Oriented Programming) con Spring. De hecho, Spring fue diseñado no para proveer la mejor solucion en AOP sino una forma sencilla de integrar aspectos en nuestras aplicaciones.
En este ejemplo quiero mostrar como se puede armar una rutina que mida el tiempo consumido por cada metodo sin llenar nuestro codigo de System.currentTimeMillis().

El primer paso es armar nuestro around advice:
package com.miempresa.training.aop.advices;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;

@Aspect
public class MiAOPTimer {
private static Log logger = LogFactory.getLog(MiAOPTimer.class);

@Around("execution(* com.miempresa.training..*.*(..))")
public Object cronometro(ProceedingJoinPoint pjp) throws Throwable{
long t1 = System.currentTimeMillis();
Object retorno = pjp.proceed();
long t2 = System.currentTimeMillis();
logger.info("Método: "+pjp.getSignature().getName()+" (" + (t2-t1) + " ms)");
return retorno;
}
}

Basicamente lo que hace es ejecutar el metodo "cronometro" para cada metodo, de cualquier clase, bajo el paquete com.miempresa.training.El nombre del metodo puede ser cualquiera, solo debemos tener en cuanta que debe tomar un ProceedingJoinPoint como parametro, retornar un objeto e invocar al metodo proceed sobre el parametro.

El archivo de configuracion de Spring debe definir el advice y el tag de autoproxies.
<beans>
<bean id="usuarioService" class="com.miempresa.training.aop.ServicioImpl"/>
<aop:aspectj-autoproxy/>
<bean id="miAOPTimer" class="com.miempresa.training.aop.advices.MiAOPTimer"/>
</beans>