Search code examples
javaspringproxyspring-aop

Is there any ways to intercept a Runnable using AOP


Here is my problem.

I have a class implements Runnable, and it is a daemon thread, which will be permanently alive during the application lifecycle.

Now I want to perform a function just like AOP enhancement to enhance this Runnable class.

It was quite easy to have that pointcut if the class is annotated with @Service or @Component. But now it is a class implememts the Runnable interface so I have not yet find any possible ways to do so without any intrusion to the original code.

Here below is my testing code:

this is the parent interface of my daemon thread

public interface MessageRunnable extends Runnable {
    void doConsume();
}



one of the working thread:

@Slf4j
public class MyDaemonThread implements MessageRunnable{
    @Override
    public void run() {
        log.info("now in run function,ready to call doConsume...");
        while(true){
            log.info("I m still alive...");
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            doConsume();
        }
    }

    @Override
    public void doConsume() {
        log.info("doConsume was called...");
    }
}



And here is the simple test:

@Component
public class TestComponent {
    private MyDaemonThread testThread;
    @PostConstruct
    public void init(){
        if(testThread==null){
            testThread=new MyDaemonThread();
            new Thread(testThread).start();
        }
    }
}



After running the application.

I can see the log is printing well, but now if I want to add a function to print now I'm in the aspect method before the doConsume function was invoked, I don't have any idea to do so without any intrude to my source code, it is acceptable to add codes ,but no modifications were allowed at all.

I wonder if there is any possible ways to let spring handle this daemon thread, then it is easy to do an aspect point cut. Otherwise, I have to change the code to add a proxy method and an interceptor do achieve the goal....


Solution

  • First of all , MyDaemonThread instance is not a spring container managed bean. The code uses new keyword to create the instance. Spring AOP can only advise a spring bean.

    Even if the MyDaemonThread is made a spring bean , it is not possible to advise doConsume() using Spring AOP with the current code ( OP mentions no modifications are allowed ).

    From the reference documentation

    Due to the proxy-based nature of Spring’s AOP framework, calls within the target object are, by definition, not intercepted.