From ae3cfff3805ae488e4cd56da3cef24aee8d79ab5 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Mon, 11 Oct 2010 18:55:21 +0000 Subject: [PATCH] fixed JodaTimeContextHolder to use a non-inheritable ThreadLocal and expose a reset method (SPR-7441); use of remove() even when being called with a null argument --- .../context/i18n/LocaleContextHolder.java | 25 +++++++++++-------- .../datetime/joda/JodaTimeContextHolder.java | 25 ++++++++++++++----- .../context/request/RequestContextHolder.java | 22 ++++++++++------ 3 files changed, 49 insertions(+), 23 deletions(-) diff --git a/org.springframework.context/src/main/java/org/springframework/context/i18n/LocaleContextHolder.java b/org.springframework.context/src/main/java/org/springframework/context/i18n/LocaleContextHolder.java index bbe245e096..5f3cabedf4 100644 --- a/org.springframework.context/src/main/java/org/springframework/context/i18n/LocaleContextHolder.java +++ b/org.springframework.context/src/main/java/org/springframework/context/i18n/LocaleContextHolder.java @@ -24,7 +24,8 @@ import org.springframework.core.NamedThreadLocal; /** * Simple holder class that associates a LocaleContext instance * with the current thread. The LocaleContext will be inherited - * by any child threads spawned by the current thread. + * by any child threads spawned by the current thread if the + * inheritable flag is set to true. * *

Used as a central holder for the current Locale in Spring, * wherever necessary: for example, in MessageSourceAccessor. @@ -58,8 +59,7 @@ public abstract class LocaleContextHolder { /** * Associate the given LocaleContext with the current thread, * not exposing it as inheritable for child threads. - * @param localeContext the current LocaleContext, or null to reset - * the thread-bound context + * @param localeContext the current LocaleContext */ public static void setLocaleContext(LocaleContext localeContext) { setLocaleContext(localeContext, false); @@ -67,19 +67,24 @@ public abstract class LocaleContextHolder { /** * Associate the given LocaleContext with the current thread. - * @param localeContext the current LocaleContext, or null to reset - * the thread-bound context + * @param localeContext the current LocaleContext, + * or null to reset the thread-bound context * @param inheritable whether to expose the LocaleContext as inheritable * for child threads (using an {@link java.lang.InheritableThreadLocal}) */ public static void setLocaleContext(LocaleContext localeContext, boolean inheritable) { - if (inheritable) { - inheritableLocaleContextHolder.set(localeContext); - localeContextHolder.remove(); + if (localeContext == null) { + resetLocaleContext(); } else { - localeContextHolder.set(localeContext); - inheritableLocaleContextHolder.remove(); + if (inheritable) { + inheritableLocaleContextHolder.set(localeContext); + localeContextHolder.remove(); + } + else { + localeContextHolder.set(localeContext); + inheritableLocaleContextHolder.remove(); + } } } diff --git a/org.springframework.context/src/main/java/org/springframework/format/datetime/joda/JodaTimeContextHolder.java b/org.springframework.context/src/main/java/org/springframework/format/datetime/joda/JodaTimeContextHolder.java index 4e3ec16b03..58c94b1482 100644 --- a/org.springframework.context/src/main/java/org/springframework/format/datetime/joda/JodaTimeContextHolder.java +++ b/org.springframework.context/src/main/java/org/springframework/format/datetime/joda/JodaTimeContextHolder.java @@ -20,27 +20,40 @@ import java.util.Locale; import org.joda.time.format.DateTimeFormatter; -import org.springframework.core.NamedInheritableThreadLocal; +import org.springframework.core.NamedThreadLocal; /** * A holder for a thread-local user {@link JodaTimeContext}. * * @author Keith Donald + * @author Juergen Hoeller * @since 3.0 */ public final class JodaTimeContextHolder { private static final ThreadLocal jodaTimeContextHolder = - new NamedInheritableThreadLocal("JodaTime Context"); + new NamedThreadLocal("JodaTime Context"); + /** + * Reset the JodaTimeContext for the current thread. + */ + public static void resetJodaTimeContext() { + jodaTimeContextHolder.remove(); + } + /** * Associate the given JodaTimeContext with the current thread. - * @param context the current JodaTimeContext, or null to clear - * the thread-bound context + * @param jodaTimeContext the current JodaTimeContext, + * or null to reset the thread-bound context */ - public static void setJodaTimeContext(JodaTimeContext context) { - jodaTimeContextHolder.set(context); + public static void setJodaTimeContext(JodaTimeContext jodaTimeContext) { + if (jodaTimeContext == null) { + resetJodaTimeContext(); + } + else { + jodaTimeContextHolder.set(jodaTimeContext); + } } /** diff --git a/org.springframework.web/src/main/java/org/springframework/web/context/request/RequestContextHolder.java b/org.springframework.web/src/main/java/org/springframework/web/context/request/RequestContextHolder.java index 0894644fd4..eaa52bc8ed 100644 --- a/org.springframework.web/src/main/java/org/springframework/web/context/request/RequestContextHolder.java +++ b/org.springframework.web/src/main/java/org/springframework/web/context/request/RequestContextHolder.java @@ -24,7 +24,9 @@ import org.springframework.util.ClassUtils; /** * Holder class to expose the web request in the form of a thread-bound - * {@link RequestAttributes} object. + * {@link RequestAttributes} object. The request will be inherited + * by any child threads spawned by the current thread if the + * inheritable flag is set to true. * *

Use {@link RequestContextListener} or * {@link org.springframework.web.filter.RequestContextFilter} to expose @@ -73,18 +75,24 @@ public abstract class RequestContextHolder { /** * Bind the given RequestAttributes to the current thread. - * @param attributes the RequestAttributes to expose + * @param attributes the RequestAttributes to expose, + * or null to reset the thread-bound context * @param inheritable whether to expose the RequestAttributes as inheritable * for child threads (using an {@link java.lang.InheritableThreadLocal}) */ public static void setRequestAttributes(RequestAttributes attributes, boolean inheritable) { - if (inheritable) { - inheritableRequestAttributesHolder.set(attributes); - requestAttributesHolder.remove(); + if (attributes == null) { + resetRequestAttributes(); } else { - requestAttributesHolder.set(attributes); - inheritableRequestAttributesHolder.remove(); + if (inheritable) { + inheritableRequestAttributesHolder.set(attributes); + requestAttributesHolder.remove(); + } + else { + requestAttributesHolder.set(attributes); + inheritableRequestAttributesHolder.remove(); + } } } -- GitLab