JEE developer with 5+ years of experience. Maheshkumar has posted 3 posts at DZone. You can read more from them at their website. View Full User Profile

Inter Aspect Communication

11.29.2010
| 3253 views |
  • submit to reddit
When you want to develop an application like “performance monitor”, you must go with AOP. Here passing values between one aspect (advice in spring) to another is not possible.

 

The following example explains how to pass a value generated in one aspect to another.

Step1: Create a Data Holder using ThreadLocal.

ThreadLocalDataHolder.java

package com.rpm.mahesh.util;

import java.util.HashMap;
import java.util.Map;

/**
* @author Maheshkumar Periyasamy
* @version 1.0 Date: Oct 5, 2010
*/
public abstract class ThreadLocalDataHolder {

private static final ThreadLocal<Map<String, Object>> THREAD_LOCAL_MAP = new ThreadLocal<Map<String, Object>>();

private ThreadLocalDataHolder() {
}

/**
* Bind the given Object to the current thread by key.
*
* @param id the String to use as key
* @param object the Object to expose
* @see #add(java.util.Map)
*/
public static void set(String id, Object object) {
currentThreadData().put(id, object);
}

/**
* Append the given Map<String,Object> to current Thread.
*
* @param map the Map to expose
* @see #set(String, Object)
*/
public static void add(Map<String, Object> map) {
currentThreadData().putAll(map);
}

/**
* Return the Object currently bound to the thread by key.
*
* @param id the String to use as key
* @return the Object currently bound to the thread,
* or <code>null</code> if none bound
*/
public static Object get(String id) {
return currentThreadData().get(id);
}

/**
* Return the Map currently bound to the thread.
*
* @return the Map currently bound to the thread,
* or empty <code>Map</code> if none bound
*/
public static Map<String, Object> getAll() {
return currentThreadData();
}

/**
* Remove the object currently bound to the thread by key.
*
* @param id the String to use as key
*/
public static void remove(String id) {
currentThreadData().remove(id);
}

/**
* Reset the ThreadLocalData for the current thread.
*/
public static void reset() {
THREAD_LOCAL_MAP.remove();
}

private static Map<String, Object> currentThreadData() {
Map<String, Object> currentMap = THREAD_LOCAL_MAP.get();
if(currentMap == null) {
currentMap = new HashMap<String, Object>();
THREAD_LOCAL_MAP.set(currentMap);
}
return currentMap;
}

}

Step2: Add necessary values to ThreadLocalDataHolder in your FirstAspect.

FirstLayer.java

package com.rpm.mahesh.util;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Aspect;

/**
* @author Maheshkumar Periyasamy
* @version 1.0 Date: Aug 19, 2010
*/
@Aspect
public abstract class FirstLayer {

public Object performAspect(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
String transactionId = "build your id here";
ThreadLocalDataHolder.set("TRANSACTION_ID", transactionId);
ThreadLocalDataHolder.set("X", "x");
ThreadLocalDataHolder.set("Y", "y");
Object returnValue = proceedingJoinPoint.proceed(proceedingJoinPoint.getArgs());
ThreadLocalDataHolder.remove("TRANSACTION_ID");
ThreadLocalDataHolder.remove("X");
ThreadLocalDataHolder.remove("Y");
return returnValue;
}
}

Step3: Access the values in your upcoming Aspects as below.

SecondLayer.java

package com.rpm.mahesh.util;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Aspect;

/**
* @author Maheshkumar Periyasamy
* @version 1.0 Date: Aug 19, 2010
*/
@Aspect
public abstract class SecondLayer {

public Object performAspect(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
//Access the values from ThreadLocalDataHolder, which are added in previous Aspect
String transactionId = (String) ThreadLocalDataHolder.get("TRANSACTION_ID");
Object returnValue = proceedingJoinPoint.proceed(proceedingJoinPoint.getArgs());
return returnValue;
}
}
3
Your rating: None Average: 3 (2 votes)
Published at DZone with permission of its author, Maheshkumar Periyasamy.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Yaozong Zhu replied on Wed, 2010/12/01 - 10:32am

Nice idea of sharing information through ThreadLocal as long as those pointcuts are within the same thread. But how about they are not?

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.