📄 contextclassloaderlocal.java
字号:
/* * Copyright 2001-2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.beanutils;import java.util.Map;import java.util.WeakHashMap;/** * A value that is provided per (thread) context classloader. * Patterned after ThreadLocal. * There is a separate value used when Thread.getContextClassLoader() is null. * This mechanism provides isolation for web apps deployed in the same container. * <strong>Note:</strong> A WeakHashMap bug in several 1.3 JVMs results in a memory leak * for those JVMs. * * @see java.lang.Thread#getContextClassLoader * @author Eric Pabst */public class ContextClassLoaderLocal { private Map valueByClassLoader = new WeakHashMap(); private boolean globalValueInitialized = false; private Object globalValue; public ContextClassLoaderLocal() { super(); } /** * Returns the initial value for this ContextClassLoaderLocal * variable. This method will be called once per Context ClassLoader for * each ContextClassLoaderLocal, the first time it is accessed * with get or set. If the programmer desires ContextClassLoaderLocal variables * to be initialized to some value other than null, ContextClassLoaderLocal must * be subclassed, and this method overridden. Typically, an anonymous * inner class will be used. Typical implementations of initialValue * will call an appropriate constructor and return the newly constructed * object. * * @return a new Object to be used as an initial value for this ContextClassLoaderLocal */ protected Object initialValue() { return null; } /** * Gets the instance which provides the functionality for {@link BeanUtils}. * This is a pseudo-singleton - an single instance is provided per (thread) context classloader. * This mechanism provides isolation for web apps deployed in the same container. * @return the object currently associated with the */ public synchronized Object get() { // synchronizing the whole method is a bit slower // but guarentees no subtle threading problems, and there's no // need to synchronize valueByClassLoader // make sure that the map is given a change to purge itself valueByClassLoader.isEmpty(); try { ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader(); if (contextClassLoader != null) { Object value = valueByClassLoader.get(contextClassLoader); if ((value == null) && !valueByClassLoader.containsKey(contextClassLoader)) { value = initialValue(); valueByClassLoader.put(contextClassLoader, value); } return value; } } catch (SecurityException e) { /* SWALLOW - should we log this? */ } // if none or exception, return the globalValue if (!globalValueInitialized) { globalValue = initialValue(); globalValueInitialized = true; }//else already set return globalValue; } /** * Sets the value - a value is provided per (thread) context classloader. * This mechanism provides isolation for web apps deployed in the same container. * * @param value the object to be associated with the entrant thread's context classloader */ public synchronized void set(Object value) { // synchronizing the whole method is a bit slower // but guarentees no subtle threading problems // make sure that the map is given a change to purge itself valueByClassLoader.isEmpty(); try { ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader(); if (contextClassLoader != null) { valueByClassLoader.put(contextClassLoader, value); return; } } catch (SecurityException e) { /* SWALLOW - should we log this? */ } // if in doubt, set the global value globalValue = value; globalValueInitialized = true; } /** * Unsets the value associated with the current thread's context classloader */ public synchronized void unset() { try { ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader(); unset(contextClassLoader); } catch (SecurityException e) { /* SWALLOW - should we log this? */ } } /** * Unsets the value associated with the given classloader */ public synchronized void unset(ClassLoader classLoader) { valueByClassLoader.remove(classLoader); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -