CTW o LTW AspectJ Weaving

By | 4 septiembre 2014

En Spring Proxy hablamos de como funcionan los proxies de Spring.

Los proxies de Spring realizan su función en la mayoría de las situaciones que van a desarrollarse en nuestra aplicación, pero a veces esto no es así.

Supongamos que desde el metodo de un @Service intentamos acceder a otro metodo anotado del mismo @Service manteniendo las funcionalidades implementadas por su anotacion. Con Spring Proxies esto no es posible, ya que la llamada se realiza de forma interna en la propia clase, es decir, como la llamada no atraviesa el proxy, desconoce la presencia de dicha anotacion.

Un ejemplo simple con @Cacheable.

@Service
public class MyService{

    @Autowired
    private FooDAO fooDAO;

    public Foo getFoo(){

        return this.getCachedFoo();
    }

    @Cacheable(...)
    private Foo getCachedFoo(){

        return this.fooDAO.getFoo();
    }
}

Como hemos dicho, @Cacheable no funcionará al ser llamado desde un metodo de la misma clase, pero podemos utilizar AspectJ para conseguir que este tipo de llamadas funcionen correctamente.

AspectJ Weaving

Básicamente, AspectJ weaver estudia la configuración de las clases y aspectos de nuestro código, y crea nuevas clases con el código de aspectos incrustado dentro de los bytecodes. Lo que traducido a un lenguaje mas simple de entender, entrelaza los diferentes caminos entre clases y aspectos.

Existen dos tipos de configuración de AspectJ weaver, CTW (Compile Time Weaving) y LTW (Load Time Weaving), la diferencia reside en el momento en que se realiza el “tejido” de clases, en tiempo de compilación (configurable en Maven) o en tiempo de carga de las clases en el contexto de la aplicación.

Para configurar AspectJ weaver en tiempo de carga en Spring tenemos que especificar en Spring su configuración mediante las anotaciones, y según sea el caso configurar Maven o el contenedor de aplicaciones (en este caso Tomcat).

CTW en Spring.

<context:spring-configured/>

Para que Maven “teja” las clases tendremos que configurarlo de la siguiente manera.

<plugin>
 <groupId>org.codehaus.mojo</groupId>
 <artifactId>aspectj-maven-plugin</artifactId>
 <configuration>
   <complianceLevel>${java.version}</complianceLevel>
   <aspectLibraries>
     <aspectLibrary>
       <groupId>org.springframework</groupId>
       <artifactId>spring-aspects</artifactId>
   </aspectLibrary>
 </aspectLibraries>
 </configuration>
 <executions>
  <execution>
    <goals>
      <goal>compile</goal>
      <goal>test-compile</goal>
    </goals>
  </execution>
</executions>
</plugin>

LTW en Spring.

<context:load-time-weaver/>

Como esta vez el “tejido” se realiza en la carga de nuestras clases, debemos especificarle al Tomcat el class loader de AspectJ en el server.xml.

Para ello.

  1. Descargamos la libreria spring-instrument-tomcat con la versión de Spring que estemos utilizando.
  2. copiamos la libreria en la carpeta de librerias de Tomcat $CATALINA_HOME/lib.
  3. Especificamos la class loader en server.xml.
<Context docBase="library-service" path="/library">
     <Loader   loaderClass="org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader"/>
</Context>
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-instrument-tomcat</artifactId>
	<version>${spring-version}</version>
</dependency>

Las dependencias en ambos casos son.

dependency>
 <groupId>org.springframework</groupId>
 <artifactId>spring-instrument</artifactId>
 <version>${spring.version}</version>
</dependency>

<dependency>
 <groupId>org.springframework</groupId>
 <artifactId>spring-aspects</artifactId>
 <version>${spring.version}</version>
</dependency>

<dependency>
 <groupId>org.aspectj</groupId>
 <artifactId>aspectjweaver</artifactId>
 <version>${aspecjtweaver.version}</version>
</dependency>

Para terminar, en el caso de la funcionalidad de caches, deberemos especificarle a Spring que en vez de usar Spring proxies, debera usar AspectJ.

<cache:annotation-driven mode="aspectj"/>
Comparte esta entrada enShare on LinkedIn0Tweet about this on Twitter0Share on Facebook0Share on Google+0

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos necesarios están marcados *