Version AspectWerkz o por otra parte... 3

Posted by Aitor Garcia Wed, 11 Jun 2003 03:09:24 GMT

Hace unos dias Merrick Schincariol publico un post para intentar aclarar lo que realmente se encuentra tras las siglas de AOP. Quizás no sea el articulo más completo sobre AOP pero si el más *claro* que he leido al respecto. Hace hincapie en algo que normalmente suele quedar enterrado bajo el mejunge de conceptos técnologicos existentes alrededor de AOP y con lo que estoy completamente de acuerdo:
"If you remember nothing else about AOP, remember that it is fundamentally about separation of concern. Filtering, interceptors and other implementation techniques that seem to dominate the AOP discussion are simply recipes for applying the AOP methodology. They are not AOP in and of themselves".
A pesar de ello hubo algo que no me acabo de convencer : la implementación del ejemplo en AspectJ. Sí , si ya se que solo es un ejemplo y que la implementación no es lo fundamental pero me gustaria ofrecer la contrapartida a ese ejemplo en otro de los frameworks existentes para AOP: Aspectwerkz. Dejo para otro post la explicación del porque de mi inclinación por AspectWerkz y no por AspectJ. Partimos de la misma clase desligada de todo aspecto no relacionado directamente con su finalidad ultima: imprimir.
public class PrintServer {
    // private variables
    // ...
    
    // constructor
    PrintServer() {
      // ...
    }
    
    public void printDocument(Document doc) {
        // ...
    }
    
    public PrinterInfo getPrinterInfo() {
        return retrievePrinterInfo();
    }
    
    // other printing methods 
    // ...
}
Y construimos el resto de requerimientos en base a aspectos de esa clase:
// Para sincronizar el acceso
import EDU.oswego.cs.dl.util.concurrent.Mutex;

import org.codehaus.aspectwerkz.advice.AroundAdvice;
import org.codehaus.aspectwerkz.joinpoint.JoinPoint;

public class SynchronizationAdvice extends AroundAdvice {

    private Mutex m_mutex = new Mutex();

    public SynchronizationAdvice() {
        super();
    }

    public Object execute(final JoinPoint joinPoint) throws Throwable {
        System.out.println("Acquiring mutex\t" + Thread.currentThread());
        m_mutex.acquire();
        System.out.println("Has mutex\t\t" + Thread.currentThread());
        Object result = joinPoint.proceed();
        m_mutex.release();
        System.out.println("Releasing mutex\t" + Thread.currentThread());
        return result;
    }
}
// para tracear las entradas y salidas...
import org.codehaus.aspectwerkz.advice.AroundAdvice;
import org.codehaus.aspectwerkz.joinpoint.JoinPoint;

public class LoggingAdvice extends AroundAdvice {

    public LoggingAdvice() {
        super();
    }

    public Object execute(final JoinPoint joinPoint) throws Throwable {
        MethodJoinPoint jp = (MethodJoinPoint)joinPoint;
        System.out.println(" entering " + jp.getTargetClass().getName() + 
                           "::" + jp.getMethodName());
        final Object result = joinPoint.proceed();
        System.out.println(" exiting " + jp.getTargetClass().getName() + 
                           "::" + jp.getMethodName());
        return result;
    }
}
// Y finalmente para cachear...
import org.codehaus.aspectwerkz.advice.AroundAdvice;
import org.codehaus.aspectwerkz.joinpoint.JoinPoint;

public class CachingAdvice extends AroundAdvice {

    protected static Object cachedResult =null;

    public CachingAdvice() {
        super();
    }

    public Object execute(final JoinPoint joinPoint) throws Throwable {

        if (cachedResult != null) {
            return cachedResult;
        }
        final Object result = joinPoint.proceed();

        cachedResult = result;
        return result;
    }
}

Como se puede observar todas los aspectos se implementan como clases Java corrientes y molientes (gran, EMHO, diferencia con respecto a AspectJ) heredando de AroundAdvice, una clase proporcionada por AspectWerkz que permite controlar el antes y el despues de la ejecucion de ciertos metodos. ¿Qué metodos?. Uuups. Se me olvidaba. Para determinar la asociación de un aspecto a un determinado punto de nuestro codigo poseemos varios metodos: uno, el que detallo a continuación por simplicidad, que permite definir en un XML estas relaciones, y dos, la utlización de los llamados atributos en tiempo de ejecución que no son sino cabeceras estilo Javadoc delante de ciertos metodos que permiten determinar, por ejemplo, que aspectos estan relacionados con el metodo en curso (de una manera muy similar a como se especifica en XDoclet). ¿Diferencias?. El segundo de los metodos implica una precompilación del codigo para generar lo que se denomina "weave model", que recopila la información de estos atributos.

Utilizando el primero de los metodos, tendriamos un XML como el siguiente:

<?xml version="1.0"?>
<aspectwerkz>

    <advice name="logging"
            class="LoggingAdvice"
            deployment-model="perJVM"
            attribute="log"/>

    <advice name="caching"
        class="CachingAdvice"
        deployment-model="perInstance">
    </advice>

    <advice name="synchronization"
        class="SynchronizationAdvice"
        deployment-model="perJVM"/>


    <aspect class="PrintServer">
        <pointcut type="method" pattern="*getPrinterInfo()">
            <advices-ref name="caching"/>
        </pointcut>
    </aspect>

    <aspect class="PrintServer">
        <pointcut type="method" pattern="*  printDocument(..)">
            <advice-ref name="synchronization"/>
        </pointcut>
    </aspect>

        <aspect class="PrintServer">
            <pointcut type="method">
                <pattern>* p*(..)</pattern>
                <advice-ref name="logging"/>
            </pointcut>
        </aspect>

</aspectwerkz>


Por ultimo resaltar la posibilidad de la utilización de *expresiones regulares* para determinar los metodos (pattern) a los que queremos aplicar el aspecto.
En fin, sigamos la implementación que sigamos, a nadie se le escapa, que aunque incipiente, AOP abre interesantes caminos en el campo del desarrollo software. Por ahora no existe una base amplia de IDEs que faciliten el desarrollo, exceptuando el proporcionado por AspectJ (aunque la gente de Eclipse ya esta trabajando en un plug-in), pero bueno todo llegará... P.D.: No , martin no se me ha olvidado lo de la conversión de patrones ;-), estoy en ello.
Comments

Leave a response

  1. Avatar
    martin Wed, 11 Jun 2003 08:35:02 GMT

    Ehh.

    Creo que lo de los patrones debería ser un trabajo en equipo ¿no? :P Estoy viendo que vas a hacer tu todo de lo lanzado que vas.

    Un saludo ;)

  2. Avatar
    Aitor Wed, 11 Jun 2003 08:54:25 GMT

    Que no, en serio, que era una broma ;-). El tema es que me he encontrado con que en varios sitios en los que se implementan patrones con AspectJ se utilizan clases como “SingletonProtocol” que per se contienen ya la estructura del patrón. No sé, estoy investigando todavía, pero ya te comentaré. Otro Saludo :-).

  3. Avatar
    lasterra@javahispano.org Wed, 11 Jun 2003 09:41:01 GMT

    Sinceramente, no tengo ni idea de AOP, solo he leido un poco pero me he fijado en dos cosas:

    Segun he entendido, XEROX tiene la patente USA e AOP, eso hace que solo en el resto del mundo se puedan hacer cosas.

    Tb me he visto, que a parte de AspectJ, y AspectWerkz,(ya ah comentado aitor la diferencia), existe uno que se llama Nanning, cuya principal caracteristica es que es solo Java, nada de descriptores, nada de cosas fuera del lenguaje. Eso, segun su autor, es una gran ventaja…puedes trabajar desde YA con cualquier IDE y puedes refactoriazar.

    A tener en cuenta.

    PS: Me parecebn lo de la sindicación en javahispano, hasta hace 4 dias no hacia visitado nunca un blog (juro que nunca tendre uno :).

Comments