I want to do some work on a graceful shutdown.
I've tried an approach shown below, but it doesn't work.
I've found a workaround (putting aspect annotation on @EventListener-marked method for ContextClosedEvent), but I want to understand, why it failed (audit() method not invoked at all without any exceptions).
@SpringBootApplication
public class Application {
public static void main(String args[]) {
SpringApplication.run(Application.class, args);
}
@AuditProcess
@PreDestroy
public void destroy() {
}
}
@Aspect
@Order(value = Ordered.HIGHEST_PRECEDENCE)
public class AuditProcessAspect {
@Pointcut("@annotation(com.aaa.bbb.annotation.AuditProcess) && execution(public * *(..))")
public void executionOfPublicAuditableMethod() {
}
@Around("executionOfPublicAuditableMethod()")
public Object audit(ProceedingJoinPoint joinPoint) {
// some business logic ...
}
}
As far as I digged into Spring 5 guts, I found that @PreDestroy is processed by CommonAnnotationBeanPostProcessor and @Aspect classes are transformed into Spring AOP Advisors by AspectJAdvisorFactory (CGLIB on JDK proxies, I guess). Thus, I don't understand, why aspect logic isn't called after sending SIGTERM to the application's JVM process. I even checked an output of System.out.println(this.getClass().getCanonicalName()), which was put into the body of the destroy() method - it looks like, for example, Application$$EnhancerBySpringCGLIB$$25f99bf7. From my current point of view, there is nothing to prevent the aspect from wrapping around @PreDestroy callback method.
Nevertheless, it doesn't work.
Can somebody explain why?