I'm using AspectJ with Spring to add logging to my application. I have an @Aspect class with an advice method that I want to trigger only for service methods invoked from a specific class. However, I'm having trouble constructing the correct pointcut expression to achieve this.
Here is my current code:
Aspect:
@Component
@Aspect
public class LoggingAspect {
private final static Logger logger = LogManager.getLogger(LoggingAspect.class);
@Pointcut("within(com.example.demo.controller.CustomerController)")
private void withinCustomerController() {
}
@Pointcut("execution(* com.example.demo.service.impl.CustomerServiceImpl.*(..))")
private void customerServiceMethods() {
}
@AfterReturning(pointcut = "withinCustomerController() && customerServiceMethods()", returning = "result")
public void logServiceResult(JoinPoint joinPoint, Object result) {
logger.info("Service method {} returned: {}", joinPoint.getSignature().getName(), result);
}
}
Controller:
@RestController
@RequestMapping(value = "/api", produces = MediaType.APPLICATION_JSON_VALUE)
@RequiredArgsConstructor
public class CustomerController {
private final CustomerService customerService;
@PostMapping(value = "/customer")
public KafkaMessage createCustomer(@RequestBody RequestDto requestDto) throws IOException {
ResponseDto responseDto = customerService.createCuistomer(requestDto);
KafkaMessage kafkaMessage = new KafkaMessage();
kafkaMessage.setContent("Event published");
return kafkaMessage;
}
}
And the Service and Implementations:
public interface CustomerService {
ResponseDto createCustomer(RequestDto requestDto);
}
@Service
public class CustomerServiceImpl implements CustomerService {
@Override
ResponseDto createCustomer(RequestDto requestDto) {
// business logic
}
}
Please note that I have all the necessary dependencies added and used @EnableAspectJAutoProxy annotation. Also, the locations used in the pointcut expressions are 100% accurate (I am using Intellij Idea).If I remove the && from the pointcut in @AfterReturning, it works perfectly. Here's the working expression:
@AfterReturning(pointcut = "customerServiceMethods()", returning = "result")
public void logServiceResult(JoinPoint joinPoint, Object result) {
logger.info("Service method {} returned: {}", joinPoint.getSignature().getName(), result);
}
But I need to make sure this aspect works only if the service method is invoked from the CustomerController.
Can someone help me construct the correct pointcut expression to achieve this behavior? Any suggestions or guidance would be greatly appreciated. Thank you!