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!