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
@Componentpublic class TenantContextInterceptor implements HandlerInterceptor {private static final ThreadLocal<String> TENANT_HOLDER = new ThreadLocal<>();public static String getCurrentTenant() {return TENANT_HOLDER.get();}@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {String tenantId = request.getHeader("X-Tenant-ID");if (tenantId != null) {TENANT_HOLDER.set(tenantId);}return true;}@Overridepublic 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.