javaaspectj

How a SpringBoot project sets the time zone for each request


I have a SpringBoot project right now, and there is already a lot of business code set to get the time, such as LocalDate.now(),LocalDateTime.now(),new Date(),new DateTime() ..... I now want to set a timezone for each request, so that the business code will perform the time fetch based on the timezone, but I don't want to change the business code because it's just too much!

I tried AspectJ for intercepting static methods, but found that it can only intercept static methods defined by itself, not static methods of JDK packages such as LocalDateTime

@Aspect
@Component
@Slf4j
public class ControllerAspect {

    @Pointcut("execution(* com.pkslow.springboot.controller..*.*(..))")
    private void testControllerPointcut() {

    }

    @Pointcut("execution(* java.time.LocalDateTime.now())")
    private void testControllerPointcut1() {

    }

    @Around("testControllerPointcut1()")
    public Object etst1(ProceedingJoinPoint pjp) throws Throwable {
        log.info("request");
        return LocalDateTime.now(ZoneId.of("America/Chicago"));
    }
}



@RestController
@RequestMapping("/test")
@Slf4j
public class TestController {

    private final TestService testService;

    public TestController(TestService testService) {
        this.testService = testService;
    }

    @GetMapping("/hello")
    public String hello() {
        System.out.println(LocalDateTime.now());
        return "Hello, pkslow.";
    }
}

I cant intercept calls to JDK classes with AspectJ


Solution

  • You need to switch from proxy-based Spring AOP to native AspectJ. Please remember to remove @Component from your native AspectJ aspect. Then, switch from execution(..) to call(..) pointcut in order to weave into the call site rather than the called method. Like you said, the called method is in the JDK and therefore unavailable for weaving.

    Disclaimer: AspectJ is not a tool to patch up problematic code for developers who are simply too lazy to refactor. That there are many places in the code where you need to refactor is not a reason not to do it, because any decent IDE has regex search & replace, which should make global changes like that quite easy. IntelliJ IDEA even has structural search & replace which is even more powerful, albeit a bit complicated to use. But regex s&r should be enough. You could also factor out all those different calls to date/time classes into a utility class and, if any need to adjust it arises, change the code in a single place. That you can patch up things here with AspectJ does not necessarily mean that you should do so.