0 Tage Serie
java / intermediate
Snippet

Vermeidung von ThreadLocal-Speicherlecks in benutzerdefinierten Spring-Interceptoren

Bei der Verwendung von ThreadLocal-Variablen in Umgebungen mit Thread-Pools (z. B. Spring MVC auf Tomcat) führt das Unterlassen des remove()-Aufrufs in afterCompletion zu Speicherlecks und veralteten Datenüberhängen auf wiederverwendeten Worker-Threads.

snippet.java
java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@Component
public class TenantContextInterceptor implements HandlerInterceptor {
private static final ThreadLocal<String> TENANT_HOLDER = new ThreadLocal<>();
public static String getCurrentTenant() {
return TENANT_HOLDER.get();
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
String tenantId = request.getHeader("X-Tenant-ID");
if (tenantId != null) {
TENANT_HOLDER.set(tenantId);
}
return true;
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
TENANT_HOLDER.remove();
}
}
spring
Erklärung
1
private static final ThreadLocal<String> TENANT_HOLDER = new ThreadLocal<>();
Hält Thread-gebundene Zustände für den aktiven HTTP-Request über Servicegrenzen hinweg.
2
TENANT_HOLDER.set(tenantId);
Speichert die Mandantenkennung in der ThreadLocalMap des aktuellen Threads.
3
TENANT_HOLDER.remove();
Entfernt den Eintrag in afterCompletion explizit, um Speicherlecks bei der Thread-Wiederverwendung zu verhindern.