I have below Java code which intercepts the method getUserDetails()
using Spring AOP and logs its execution time. The method calculateExecutionTime
gets executed in the same thread as getUserDetails()
.
package com.poc.app.data;
import org.springframework.stereotype.Repository;
@Repository
public class User {
public String getUserDetails() {
return "user details";
}
}
package com.poc.app.aspect;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;
@Aspect
@Configuration
public class ExecutionTimeAspect {
private Logger logger = LoggerFactory.getLogger(this.getClass());
@Around("execution(* com.poc.app..*.*(..))")
public Object calculateExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
long startTime = System.currentTimeMillis();
Object returnValue = joinPoint.proceed();
long timeTaken = System.currentTimeMillis() - startTime;
logger.info("Time taken by {} to complete execution is: {}", joinPoint, timeTaken);
return returnValue;
}
}
Question: I am working on creating another Aspect to capture runtime data of various methods (like the input parameter values, the return values) using @Before and @After Spring AOP advices.
getUserDetails
in this example?I don't think that its a responsibility of AOP framework to provide multi threaded execution. The business code gets wrapped by advices and basically you can run the code in advice before the business code, after the business code or around the business code (by possibly omitting the business code execution).
Having said that, there is nothing that stops you to spawn a thread (or in a more realistic scenario, probably, using a thread from thread pool) from within an advice and "offload" the potentially expensive execution to that thread.
Of course it will be the responsibility of the programmer to handle possible errors that might arise during the code execution (both the aspect's code and the business code itself).
This probably answers also your second question: you should be ok with these 3 types , no need to create additional types for that.
In a pseudo code it looks like this:
@Aspect
@Configuration
public class ExecutionTimeAspect {
private ThreadPool theadPool = ... // you can user executors of java, maybe queues for async task execution and so on, I name it 'generic thread pool' here, which is technology agnostic
@Around("execution(* com.poc.app..*.*(..))")
public Object execute(ProceedingJoinPoint joinPoint) throws Throwable {
threadPool.execute(this::executeExpensiveOperation); // this is off-loaded to another thread actually
return joinPoint.proceed();
}
private void executeExpensiveOperation() {
// this should be run in a separate thread
}
}