Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Asynchronous execution aspect using AspectJ

Here is the problem -

I was using @Async provided by Spring to execute some methods asynchronously. However, because it is proxy based, it wouldn't work if the method is called from within the same class. I do need my async methods to be called from within the same class.

I know if I use AspectJ instead of Spring AOP, I will be able to do that.

So my question is, is there a way to use Spring's @Async and load time weave it? Or, is there an AspectJ based async execution aspect already written that I can use, instead of writing my own?

like image 480
Mahesh Avatar asked Jun 28 '13 20:06

Mahesh


People also ask

What is AspectJ used for?

AspectJ Provides a Standard Mechanism to Handle a Crosscutting Concern. In the example shown above, we are doing a null validation and throwing an IllegalArgumentException when the request is null. This way we make sure that whenever an argument is null, we get the same uniform behavior.

Is AOP asynchronous?

So the answer is: Yes, aspect advices like @Before or @After for Spring AOP will be executed asynchronously.

What is the use of AspectJ in Spring?

Aspect: An aspect is a class that implements enterprise application concerns that cut across multiple classes, such as transaction management. Aspects can be a normal class configured through Spring XML configuration or we can use Spring AspectJ integration to define a class as Aspect using @Aspect annotation.


2 Answers

Yes, annotate a concrete class' method with @Async, put spring-aspects JAR (which contains the async aspect) into your classpath, use <task:annotation-driven mode="aspectj" /> in your Spring config and apply either compile-time or load-time weaving, referencing spring-aspects as an aspect library.

like image 103
Jukka Avatar answered Sep 28 '22 14:09

Jukka


One thing you can do is toss together a bean whose only purpose is to run things asynchronously and pass the work to it inside the method. This may not make the API as pretty if you like to put @Async on your interfaces or whatever, but it gets the job done.

public interface AsyncExecutor {

  void runAsynchronously(Runnable r);
}

public class SpringAOPAsyncExecutor implements AsyncExecutor {

  @Async
  @Override
  public void runAsynchronously(Runnable r) {
    r.run();
  }
}

public MyService implements SomeInterface {

  @Autowired
  private AsyncExecutor springAOPAsyncExecutor;

  public ObjectHolder calculateAsychronously() {
    final ObjectHolder resultHolder = new ObjectHolder();
    springAOPAsyncExecutor.runAsynchronously ( new Runnable() {
      public void run() {
        //do some calculatin
        resultHolder.setValue(whatevs);
      }
    });
    return resultHolder;
  }
}
like image 38
Affe Avatar answered Sep 28 '22 13:09

Affe