Archive

Posts Tagged ‘aop’

How to enable Load Time Weaving of Aspects in Spring

February 9th, 2015 No comments

We will talk about weaving in general and how to enable weaving in your spring application. You would have heard of weaving mostly with AOP programming and normally with Spring, but before we dive into Spring AOP, let us understand weaving.

What is weaving in programming ?

Weaving in general is a programmatic transformation which essentially means processing of a code to produce a desired output.

In Spring AOP makes it possible to modularize and separate logging, transaction like services and apply them declaratively to the components Hence programmer can focus on specific concerns. Aspects are wired into objects in the spring XML file in the way as JavaBean. This is also known as ‘Weaving’.

There are three types of weaving

  • Compile time
  • Post compile time
  • Run time

We can have source level weaving as in C++ using pre processors. In Java we can have byte code in which you add code at run time around your existing code.

The AspectJ weaver takes class files as input and produces class files as output. The weaving process itself can take place at one of three different times: compile-time, post-compile time, and load-time. The class files produced by the weaving process (and hence the run-time behaviour of an application) are the same regardless of the approach chosen.

  • Compile-time weaving is the simplest approach. When you have the source code for an application, ajc will compile from source and produce woven class files as output. The invocation of the weaver is integral to the ajc compilation process. The aspects themselves may be in source or binary form. If the aspects are required for the affected classes to compile, then you must weave at compile-time. Aspects are required, e.g., when they add members to a class and other classes being compiled reference the added members.
  • Post-compile weaving (also sometimes called binary weaving) is used to weave existing class files and JAR files. As with compile-time weaving, the aspects used for weaving may be in source or binary form, and may themselves be woven by aspects.
  • Load-time weaving (LTW) is simply binary weaving defered until the point that a class loader loads a class file and defines the class to the JVM. To support this, one or more “weaving class loaders”, either provided explicitly by the run-time environment or enabled through a “weaving agent” are required.

You may also hear the term “run-time weaving”. We define this as the weaving of classes that have already been defined to the JVM (without reloading those classes). AspectJ 5 does not provide explicit support for run-time weaving although simple coding patterns can support dynamically enabling and disabling advice in aspects.

We are going to show compile time weaving in the application. A preprocessor and aspect weaver are used to transform the original non-aspect code into a woven code. Thus, the original code is altered only once at compile-time.

Why did we use compile time weaving ? Because it leads to quicker startup time in your application. Drawback is that anytime the aspect gets modified, all code segments which are weaved by this aspect, must get recompiled.

Steps to enable Load Time Weaving of Aspects in your application

Step 1:

Add the following to your application context to inform Spring to activate the AOP injection.

</pre>
<div>
<pre><context:spring-configured/>

Step 2:
Add the @Configurable annotation to your entity. Use @Autowired annotation to inject dependencies

</pre>
<div>
<pre>@Configurable
public class MyClass{
...
@Autowired
Private transient MyRepository

}

Step 3:
To tell Spring/AspectJ which domain objects are going to be “woven”. Create a new directory “META-INF” in a directory which is included on the classpath. Add inside this directory a new file called “aop.xml”.

NOTE: Use the most restrictive packages possible. The smaller the code base inspected and instrumented, the faster startup time will be and the less runtime overhead

Add the following to that file:


<!DOCTYPE aspectj PUBLIC
"-//AspectJ//DTD//EN" "http://www.eclipse.org/aspectj/dtd/aspectj.dtd">
<aspectj>
<weaver options="-Xreweavable -showWeaveInfo  -XmessageHandlerClass:org.springframework.aop.aspectj.AspectJWeaverMessageHandler">
<exclude within="*..*CGLIB*" />
<exclude within="*..*javassist*" />
<include within="com..*.mypackage..*"/>
</weaver>
<aspects>
<aspect name="org.springframework.beans.factory.aspectj.AbstractInterfaceDrivenDependencyInjectionAspect"/>
</aspects>
</aspectj>

This adds the @Configurable support to those beans included in any sub package of the “com…*.mypackage” package and excludes files from CGLIB or javaassist packages and resolves weird errors related to cglib proxy class or javaassist. Step 4: Finally, you must tell the JVM to use the AspectJ “Java Agent”. This is needed for AspectJ to intercept method calls.This can be enabled when starting the JVM using the following argument:

</pre>
<div>
<pre>-javaagent:c:/devtk/LAS/lib/spring-instrument.jar

Aspect Oriented Programming (AOP) with Spring

December 16th, 2009 7 comments

Aspects Oriented programming(AOP) is another way of programming in Spring. Instead of Object oriented programming, in which the key unit is class , in AOP the key unit is aspect.

AOP framework is part of the Spring and comes bundled with it. No additional installation is required. Spring AOP is implemented in pure Java and can be used in a web container or enterprise server. Before we move ahead with an example , let us look at some terminologies which we will be using in this application

Aspect: a modularization of a concern that cuts across multiple classes. Transaction management is a good example of a crosscutting concern in Java EE applications.
Join point: a point during the execution of a program, such as the execution of a method or the handling of an exception. In Spring AOP, a join point always represents a method execution.
Advice: action taken by an aspect at a particular join point. Different types of advice include “around,” “before” and “after” advice. (Advice types are discussed below.) Many AOP frameworks, including Spring, model an advice as an interceptor, maintaining a chain of interceptors around the join point.
Pointcut: A predicate that matches join points. Advice is associated with a pointcut expression and runs at any join point matched by the pointcut (for example, the execution of a method with a certain name). The concept of join points as matched by pointcut expressions is central to AOP, and Spring uses the AspectJ pointcut expression language by default.
Now let us see what is really an aspect and how it can be useful in an application. This is a simple application to demonstrate how a cross cutting concern is being invoked.

Assume that in an application you have to check the status of user before every save. The user can be updated by various services and it is important to verify the user whose details are being updated is valid any more or not. It might happen that some one else has updated the state of user while you are trying to save the records. I know you might want to do this by using hibernate but here we are concerned with the sate of object and not its version.

In your application-Context.xml , you will define the aspect and the pointcut as


<?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:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop"
 xmlns:context="http://www.springframework.org/schema/context" xmlns:jee="http://www.springframework.org/schema/jee"
 xmlns:tx="http://www.springframework.org/schema/tx"
 xsi:schemaLocation="
 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
 http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
 http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd
 http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">

<context:property-placeholder location="classpath:component.properties"/>

<!-- Connection Pool -->
 <bean id="dataSource" destroy-method="close">
 <property name="driverClass" value="${jdbc.driverClass}"/>
 <property name="jdbcUrl" value="${jdbc.url}"/>
 <property name="user" value="${jdbc.username}"/>
 <property name="password" value="${jdbc.password}"/>
 </bean>

<!-- JPA EntityManagerFactory -->
 <bean id="entityManagerFactory"
 p:dataSource-ref="dataSource">
 <property name="jpaVendorAdapter">
 <bean>
 <property name="database" value="${jpa.database}"/>
 <property name="showSql" value="${jpa.showSql}"/>
 </bean>
 </property>
 </bean>

<!-- Transaction manager for a single JPA EntityManagerFactory (alternative to JTA) -->
 <bean id="transactionManager"
 p:entityManagerFactory-ref="entityManagerFactory"/>

<!-- Activates various annotations to be detected in bean classes for eg @Autowired-->
 <context:annotation-config/>

<!-- enable the configuration of transactional behavior based on annotations -->
 <tx:annotation-driven transaction-manager="transactionManager"/>

<!-- Property Configurator -->
 <bean id="propertyConfigurer">
 <property name="location" value="jdbc.properties"/>
 </bean>

<context:component-scan base-package="cs.comp.dao"/>

<bean id="geekTransactionService"/>

<bean id="validationService"/>

<aop:config>
 <aop:aspect id="geekServiceAspect" ref="validationService">
 <aop:pointcut id="geekServicePointCut"
 expression="execution(* cs.comp.service.GeekTransactionService.addRecords*(..))" />
 <aop:before
 pointcut-ref="geekServicePointCut"
 method="isValid"/>
 </aop:aspect>
 </aop:config>

</beans>

Make Sure you have aspectjweaver.jar and aspectjrt.jar in your classpath along with other jar files.

Here is the service class GeekTransactionServiceImpl


public class GeekTransactionServiceImpl implements GeekTransactionService {

/** DAO variable */

@Autowired

GeekUserDAO geekUserDAO;

@Transactional(readOnly = false, propagation = Propagation.<em>REQUIRES_NEW</em>)

public void addRecords(){

try {

//do some processing and save to dbase.

System.out.println( " Saving records ");

} catch (Exception e) {

e.printStackTrace();

log.fatal(

"Problem in updating records ", e);

}

}

ValidationService Interface


public interface ValidationService {

public boolean isValid() throws Exception ;

}
 ValidationServiceImpl Class

public class ValidationServiceImpl {

public boolean isValid() throws Exception{

boolean isValid = false ;

System.out.println( " Hitting AOP Point cut ");

return isValid;

}

}

And this is the class to run the code


public class TestService {

public static void main(String args[]){

GeekTransactionService geekTransactionService ;

ClassPathXmlApplicationContext appContext = new ClassPathXmlApplicationContext(new String[] {

"applicationContext.xml" });

geekTransactionService = (GeekTransactionService) appContext.getBean("geekTransactionService");

geekTransactionService.addRecords();

}

}

When you run the TestService class , you will see the output

Hitting AOP Point cut

Saving records

Now let us understand how this works. Look at the definition below in applicationContext.xml


<bean id="geekTransactionService" class="cs.comp.service.GeekTransactionServiceImpl"/>

<bean id="validationService" class="cs.comp.aop.ValidationServiceImpl"/>

<aop:config>

<aop:aspect id="geekServiceAspect" ref="validationService">

<aop:pointcut id="geekServicePointCut"

expression="execution(* cs.comp.service.GeekTransactionService.addRecords*(..))" />

<aop:before pointcut-ref="geekServicePointCut"

method="isValid"/>

</aop:aspect>

</aop:config>

</beans>

The geekservicePointCut states that whenever any method of geekTransaction service which starts with addRecords and with any number of parameters is invoked, invoke the isValid method of the PointCut.

Let us assume there is another method addrecordsForXYZ in GeekService and is called this way


@Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
public void addRecords(){
try {

//do some processing and save to dbase.

System.out.println( " Saving records ");

} catch (Exception e) {

e.printStackTrace();

log.fatal(

"Problem in updating records ", e);

}

addRecordsXYZ();

}

Since aspect would be invoked whenever there is call addRecord*.(–) method , do you think aspect will be invoked ?

Would like to know your response.

Categories: Programming / tutorials Tags: ,