Я кодирую перехватчик для записи стоимости времени запроса. Я использовал ThreadLocal, чтобы создать время начала моего запроса в preHandler и использовать его в postHandler.code следующим образом:
private final ThreadLocal<Long> inTimeLocal = new ThreadLocal<>();
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
MDC.put("traceId", UUID.randomUUID().toString());
final long beforeHandler = System.currentTimeMillis();
inTimeLocal.set(beforeHandler);
return super.preHandle(request, response, handler);
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
final long afterHandler = System.currentTimeMillis();
long beforeHandler = inTimeLocal.get();
inTimeLocal.remove();
final long interval = afterHandler - beforeHandler;
String traceId = MDC.get("traceId");
Log.info("traceId:{},method:{},interval:{}",traceId,handler instanceof HandlerMethod ?((HandlerMethod) handler).getShortLogMessage():"",interval);
super.postHandle(request, response, handler, modelAndView);
}
, но если обработчик выдает исключение, postHandler не будет работать, в этом случае , я хочу зарегистрировать резервное удаление в ThreadLocal. Для этого я использую таймер. код вроде этого:
private final HashedWheelTimer hashedWheelTimer = new HashedWheelTimer(100, TimeUnit.MILLISECONDS);
private final ThreadLocal<Long> inTimeLocal = new ThreadLocal<>();
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
MDC.put("traceId", UUID.randomUUID().toString());
final long beforeHandler = System.currentTimeMillis();
inTimeLocal.set(beforeHandler);
hashedWheelTimer.newTimeout(timeout->{
inTimeLocal.remove();
},65L,TimeUnit.SECONDS);
return super.preHandle(request, response, handler);
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
final long afterHandler = System.currentTimeMillis();
String traceId = MDC.get("traceId");
long beforeHandler = inTimeLocal.get();
final long interval = afterHandler - beforeHandler;
Log.info("traceId:{},method:{},interval:{}",traceId,handler instanceof HandlerMethod ?((HandlerMethod) handler).getShortLogMessage():"",interval);
super.postHandle(request, response, handler, modelAndView);
}
Но таймер создал новый поток для обработки задачи. Таким образом, удаление не вступит в силу.
Есть ли способ зарегистрировать резервное удаление для ThreadLocal