001/*002 * Copyright 2002-2017 the original author or authors.003 *004 * Licensed under the Apache License, Version 2.0 (the "License");005 * you may not use this file except in compliance with the License.006 * You may obtain a copy of the License at007 *008 * https://www.apache.org/licenses/LICENSE-2.0009 *010 * Unless required by applicable law or agreed to in writing, software011 * distributed under the License is distributed on an "AS IS" BASIS,012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.013 * See the License for the specific language governing permissions and014 * limitations under the License.015 */016017package org.springframework.web.context.request;018019import org.springframework.beans.factory.ObjectFactory;020import org.springframework.beans.factory.config.Scope;021import org.springframework.lang.Nullable;022023/**024 * Abstract {@link Scope} implementation that reads from a particular scope025 * in the current thread-bound {@link RequestAttributes} object.026 *027 * <p>Subclasses simply need to implement {@link #getScope()} to instruct028 * this class which {@link RequestAttributes} scope to read attributes from.029 *030 * <p>Subclasses may wish to override the {@link #get} and {@link #remove}031 * methods to add synchronization around the call back into this super class.032 *033 * @author Rod Johnson034 * @author Juergen Hoeller035 * @author Rob Harrop036 * @since 2.0037 */038public abstract class AbstractRequestAttributesScope implements Scope {039040 @Override041 public Object get(String name, ObjectFactory<?> objectFactory) {042 RequestAttributes attributes = RequestContextHolder.currentRequestAttributes();043 Object scopedObject = attributes.getAttribute(name, getScope());044 if (scopedObject == null) {045 scopedObject = objectFactory.getObject();046 attributes.setAttribute(name, scopedObject, getScope());047 // Retrieve object again, registering it for implicit session attribute updates.048 // As a bonus, we also allow for potential decoration at the getAttribute level.049 Object retrievedObject = attributes.getAttribute(name, getScope());050 if (retrievedObject != null) {051 // Only proceed with retrieved object if still present (the expected case).052 // If it disappeared concurrently, we return our locally created instance.053 scopedObject = retrievedObject;054 }055 }056 return scopedObject;057 }058059 @Override060 @Nullable061 public Object remove(String name) {062 RequestAttributes attributes = RequestContextHolder.currentRequestAttributes();063 Object scopedObject = attributes.getAttribute(name, getScope());064 if (scopedObject != null) {065 attributes.removeAttribute(name, getScope());066 return scopedObject;067 }068 else {069 return null;070 }