3

While using @Around aspect and Spring boot. What would be the best approach to create a variable before joinPoint execution, make it available during joinPoint execution to collect data in it and after joinPoint execution use the data collected in variable?

Assuming it is a multithreaded environment.

@Aspect
@EnableAspectJAutoProxy
public class SomeConfig {

    @Around(value = "@annotation(path.to.my.annotation.here)", argNames = "specificArg")
    public void doLogic(ProceedingJoinPoint joinPoint) throws Throwable {

        //create local variable X for thread execution here
        try{
            joinPoint.proceed(); //or joinPoint.proceed(Object[]);
        }
        finally {
        //use local variable X to do some logic
        }
    }
}

Don't want to change method signatures using custom annotation.

Any design pattern, or implementation example would help alot. Thanks!

nash
  • 105
  • 1
  • 10

1 Answers1

1

You might create a safe ThreadLocal and set the variable that you want and later use it.

public class VariableContext {

    private static ThreadLocal<String> currentVariable = new ThreadLocal<String>() {
        @Override
        protected String initialValue() {
            return "";
        }
    };

    public static void setCurrentVariable(String tenant) {
        currentVariable.set(tenant);
    }

    public static String getCurrentVariable() {
        return currentVariable.get();
    }

    public static void clear() {
        currentVariable.remove();
    }

}

and here you can use it or in other classes.

@Aspect
@EnableAspectJAutoProxy
public class SomeConfig {

    @Around(value = "@annotation(path.to.my.annotation.here)", argNames = "specificArg")
    public void doLogic(ProceedingJoinPoint joinPoint) throws Throwable {

        //create local variable X for thread execution here
        try{
            joinPoint.proceed(); //or joinPoint.proceed(Object[]);
        }
        finally {
        //use local variable X to do some logic
            VariableContext.setCurrentVariable("someValue");
            String result = VariableContext.getCurrentVariable();

        }
    }
}
Jonathan JOhx
  • 5,784
  • 2
  • 17
  • 33
  • is it safe to do - ```VariableContext.setCurrentVariable("someValue");``` before `joinPoint.proceed()` in `doLogic()` - then during joinPoint execution `VariableContext.getCurrentVariable();` and add data to it - then in `doLogic()` finally block do a `VariableContext.getCurrentVariable();`, perform custom logic on collected data. And in the end of `doLogic()` do `VariableContext.clear();` ? @JonathanJohx – nash Aug 29 '19 at 19:22
  • The approach helped me achieve what i was looking for. Just for others reference, where i stumbled. avoid using `InheritableThreadLocal` when creating asynchronous threads on aspects in spring boot using @Async. Thread pool executor management done by spring framework inherits threadLocal object only when new threads were being created. Reusing thread in wait state did not inherit threadLocal Object from parent thread. – nash Oct 08 '19 at 14:23