Enforce non-null value from getBean and at injection points

Bean-derived null values may still get passed into bean properties and injection points but only if those are declared as non-required. Note that getBean will never return null; a manual bean.equals(null) / "null".equals(bean.toString()) check identifies expected null values now.  This will only ever happen with custom FactoryBeans or factory methods returning null - and since all common cases are handled by autowiring or bean property values in bean definitions, there should be no need to ever manually check for such a null value received from getBean.

Issue: SPR-15829
This commit is contained in:
Juergen Hoeller 2017-08-18 00:11:35 +02:00
parent 10dcaa9bf6
commit b94302b5bd
30 changed files with 344 additions and 204 deletions

View File

@ -45,7 +45,6 @@ public interface ObjectFactory<T> {
* @return the resulting instance
* @throws BeansException in case of creation errors
*/
@Nullable
T getObject() throws BeansException;
}

View File

@ -40,7 +40,6 @@ public interface ObjectProvider<T> extends ObjectFactory<T> {
* @throws BeansException in case of creation errors
* @see #getObject()
*/
@Nullable
T getObject(Object... args) throws BeansException;
/**

View File

@ -725,7 +725,7 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
@Override
public Object resolveShortcut(BeanFactory beanFactory) {
return resolveCandidate(this.shortcut, this.requiredType, beanFactory);
return beanFactory.getBean(this.shortcut, this.requiredType);
}
}

View File

@ -268,7 +268,6 @@ public interface AutowireCapableBeanFactory extends BeanFactory {
* @return the bean instance to use, either the original or a wrapped one
* @throws BeansException if the initialization failed
*/
@Nullable
Object initializeBean(Object existingBean, String beanName) throws BeansException;
/**
@ -281,7 +280,6 @@ public interface AutowireCapableBeanFactory extends BeanFactory {
* @throws BeansException if any post-processing failed
* @see BeanPostProcessor#postProcessBeforeInitialization
*/
@Nullable
Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException;
@ -295,7 +293,6 @@ public interface AutowireCapableBeanFactory extends BeanFactory {
* @throws BeansException if any post-processing failed
* @see BeanPostProcessor#postProcessAfterInitialization
*/
@Nullable
Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException;

View File

@ -252,7 +252,7 @@ public class DependencyDescriptor extends InjectionPoint implements Serializable
public Object resolveCandidate(String beanName, Class<?> requiredType, BeanFactory beanFactory)
throws BeansException {
return beanFactory.getBean(beanName, requiredType);
return beanFactory.getBean(beanName);
}

View File

@ -87,7 +87,6 @@ public interface SmartInstantiationAwareBeanPostProcessor extends InstantiationA
* (typically with the passed-in bean instance as default)
* @throws org.springframework.beans.BeansException in case of errors
*/
@Nullable
default Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
return bean;
}

View File

@ -410,37 +410,36 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
}
@Override
@Nullable
public Object initializeBean(Object existingBean, String beanName) {
return initializeBean(beanName, existingBean, null);
}
@Override
@Nullable
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
result = beanProcessor.postProcessBeforeInitialization(result, beanName);
if (result == null) {
return null;
Object current = beanProcessor.postProcessBeforeInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
@Override
@Nullable
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
result = beanProcessor.postProcessAfterInitialization(result, beanName);
if (result == null) {
return null;
Object current = beanProcessor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
@ -461,7 +460,6 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
* @see #doCreateBean
*/
@Override
@Nullable
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
@ -535,7 +533,6 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
* @see #instantiateUsingFactoryMethod
* @see #autowireConstructor
*/
@Nullable
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
@ -547,23 +544,23 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
mbd.resolvedTargetType = beanType;
final Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
if (beanType != null) {
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
@ -583,9 +580,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
Object exposedObject = bean;
try {
populateBean(beanName, mbd, instanceWrapper);
if (exposedObject != null) {
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
@ -624,15 +619,13 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
}
}
if (bean != null) {
// Register bean as disposable.
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
// Register bean as disposable.
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
@ -904,17 +897,13 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
* @param bean the raw bean instance
* @return the object to expose as bean reference
*/
@Nullable
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, @Nullable Object bean) {
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
Object exposedObject = bean;
if (bean != null && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
if (exposedObject == null) {
return null;
}
}
}
}
@ -954,9 +943,6 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
instance = resolveBeforeInstantiation(beanName, mbd);
if (instance == null) {
bw = createBeanInstance(beanName, mbd, null);
if (bw == null) {
return null;
}
instance = bw.getWrappedInstance();
}
}
@ -995,9 +981,6 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
instance = resolveBeforeInstantiation(beanName, mbd);
if (instance == null) {
BeanWrapper bw = createBeanInstance(beanName, mbd, null);
if (bw == null) {
return null;
}
instance = bw.getWrappedInstance();
}
}
@ -1097,7 +1080,6 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
* @see #autowireConstructor
* @see #instantiateBean
*/
@Nullable
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// Make sure bean class is actually resolved at this point.
Class<?> beanClass = resolveBeanClass(mbd, beanName);
@ -1184,9 +1166,8 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
* @see #obtainFromSupplier
*/
@Override
@Nullable
protected Object getObjectForBeanInstance(
@Nullable Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
String currentlyCreatedBean = this.currentlyCreatedBean.get();
if (currentlyCreatedBean != null) {
@ -1262,7 +1243,6 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
* @return a BeanWrapper for the new instance
* @see #getBean(String, Object[])
*/
@Nullable
protected BeanWrapper instantiateUsingFactoryMethod(
String beanName, RootBeanDefinition mbd, @Nullable Object[] explicitArgs) {
@ -1698,7 +1678,6 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
* @see #invokeInitMethods
* @see #applyBeanPostProcessorsAfterInitialization
*/
@Nullable
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
@ -1715,18 +1694,16 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
if (wrappedBean != null) {
try {
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
try {
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;

View File

@ -380,9 +380,13 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
// corner cases, in particular in functional configuration and Kotlin scenarios.
// A future Spring generation might eventually forbid null values completely
// and throw IllegalStateExceptions instead of leniently passing them through.
if (requiredType != null && bean != null && !requiredType.isInstance(bean)) {
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
return getTypeConverter().convertIfNecessary(bean, requiredType);
T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
return convertedBean;
}
catch (TypeMismatchException ex) {
if (logger.isDebugEnabled()) {
@ -421,9 +425,6 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
return !BeanFactoryUtils.isFactoryDereference(name);
}
}
else if (containsSingleton(beanName)) {
return true;
}
// No singleton instance found -> check bean definition.
BeanFactory parentBeanFactory = getParentBeanFactory();
@ -496,7 +497,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
// Check manually registered singletons.
Object beanInstance = getSingleton(beanName, false);
if (beanInstance != null) {
if (beanInstance != null && beanInstance.getClass() != NullBean.class) {
if (beanInstance instanceof FactoryBean) {
if (!BeanFactoryUtils.isFactoryDereference(name)) {
Class<?> type = getTypeForFactoryBean((FactoryBean<?>) beanInstance);
@ -605,7 +606,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
// Check manually registered singletons.
Object beanInstance = getSingleton(beanName, false);
if (beanInstance != null) {
if (beanInstance != null && beanInstance.getClass() != NullBean.class) {
if (beanInstance instanceof FactoryBean && !BeanFactoryUtils.isFactoryDereference(name)) {
return getTypeForFactoryBean((FactoryBean<?>) beanInstance);
}
@ -613,10 +614,6 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
return beanInstance.getClass();
}
}
else if (containsSingleton(beanName) && !containsBeanDefinition(beanName)) {
// null instance registered
return null;
}
// No singleton instance found -> check bean definition.
BeanFactory parentBeanFactory = getParentBeanFactory();
@ -1014,10 +1011,6 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
if (beanInstance != null) {
return (beanInstance instanceof FactoryBean);
}
else if (containsSingleton(beanName)) {
// null instance registered
return false;
}
// No singleton instance found -> check bean definition.
if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) {
@ -1631,13 +1624,8 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
* @param mbd the merged bean definition
* @return the object to expose for the bean
*/
@Nullable
protected Object getObjectForBeanInstance(
@Nullable Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
if (beanInstance == null) {
return null;
}
Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
// Don't let calling code try to dereference the factory if the bean isn't a factory.
if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {
@ -1782,7 +1770,6 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
* @return a new instance of the bean
* @throws BeanCreationException if the bean could not be created
*/
@Nullable
protected abstract Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException;

View File

@ -205,6 +205,9 @@ class BeanDefinitionValueResolver {
"Error converting typed String value for " + argName, ex);
}
}
else if (value instanceof NullBean) {
return null;
}
else {
return evaluate(value);
}
@ -309,12 +312,13 @@ class BeanDefinitionValueResolver {
Object innerBean = this.beanFactory.createBean(actualInnerBeanName, mbd, null);
if (innerBean instanceof FactoryBean) {
boolean synthetic = mbd.isSynthetic();
return this.beanFactory.getObjectFromFactoryBean(
innerBean = this.beanFactory.getObjectFromFactoryBean(
(FactoryBean<?>) innerBean, actualInnerBeanName, !synthetic);
}
else {
return innerBean;
if (innerBean instanceof NullBean) {
innerBean = null;
}
return innerBean;
}
catch (BeansException ex) {
throw new BeanCreationException(
@ -344,8 +348,10 @@ class BeanDefinitionValueResolver {
/**
* Resolve a reference to another bean in the factory.
*/
@Nullable
private Object resolveReference(Object argName, RuntimeBeanReference ref) {
try {
Object bean;
String refName = ref.getBeanName();
refName = String.valueOf(doEvaluate(refName));
if (ref.isToParent()) {
@ -355,13 +361,16 @@ class BeanDefinitionValueResolver {
"Can't resolve reference to bean '" + refName +
"' in parent factory: no parent factory available");
}
return this.beanFactory.getParentBeanFactory().getBean(refName);
bean = this.beanFactory.getParentBeanFactory().getBean(refName);
}
else {
Object bean = this.beanFactory.getBean(refName);
bean = this.beanFactory.getBean(refName);
this.beanFactory.registerDependentBean(refName, this.beanName);
return bean;
}
if (bean instanceof NullBean) {
bean = null;
}
return bean;
}
catch (BeansException ex) {
throw new BeanCreationException(

View File

@ -348,7 +348,6 @@ class ConstructorResolver {
* method, or {@code null} if none (-> use constructor argument values from bean definition)
* @return a BeanWrapper for the new instance
*/
@Nullable
public BeanWrapper instantiateUsingFactoryMethod(
final String beanName, final RootBeanDefinition mbd, @Nullable final Object[] explicitArgs) {
@ -576,9 +575,6 @@ class ConstructorResolver {
mbd, beanName, this.beanFactory, factoryBean, factoryMethodToUse, argsToUse);
}
if (beanInstance == null) {
return null;
}
bw.setBeanInstance(beanInstance);
return bw;
}

View File

@ -1129,14 +1129,27 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
if (autowiredBeanNames != null) {
autowiredBeanNames.add(autowiredBeanName);
}
return (instanceCandidate instanceof Class ?
descriptor.resolveCandidate(autowiredBeanName, type, this) : instanceCandidate);
if (instanceCandidate instanceof Class) {
instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
}
Object result = instanceCandidate;
if (result instanceof NullBean) {
if (isRequired(descriptor)) {
raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
result = null;
}
if (!ClassUtils.isAssignableValue(type, result)) {
throw new BeanNotOfRequiredTypeException(autowiredBeanName, type, instanceCandidate.getClass());
}
return result;
}
finally {
ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
}
}
@Nullable
private Object resolveMultipleBeans(DependencyDescriptor descriptor, @Nullable String beanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) {
@ -1500,7 +1513,8 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
isAutowireCandidate(beanName, mbd, descriptor, getAutowireCandidateResolver())) {
// Probably a proxy interfering with target type match -> throw meaningful exception.
Object beanInstance = getSingleton(beanName, false);
Class<?> beanType = (beanInstance != null ? beanInstance.getClass() : predictBeanType(beanName, mbd));
Class<?> beanType = (beanInstance != null && beanInstance.getClass() != NullBean.class) ?
beanInstance.getClass() : predictBeanType(beanName, mbd);
if (beanType != null && !type.isAssignableFrom(beanType)) {
throw new BeanNotOfRequiredTypeException(beanName, type, beanType);
}
@ -1526,7 +1540,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
}
@Override
public Object resolveCandidate(String beanName, Class<?> requiredType, BeanFactory beanFactory) {
return (!ObjectUtils.isEmpty(args) ? beanFactory.getBean(beanName, requiredType, args) :
return (!ObjectUtils.isEmpty(args) ? beanFactory.getBean(beanName, args) :
super.resolveCandidate(beanName, requiredType, beanFactory));
}
};
@ -1615,18 +1629,20 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
}
@Override
@Nullable
public Object getObject() throws BeansException {
if (this.optional) {
return createOptionalDependency(this.descriptor, this.beanName);
}
else {
return doResolveDependency(this.descriptor, this.beanName, null, null);
Object result = doResolveDependency(this.descriptor, this.beanName, null, null);
if (result == null) {
throw new NoSuchBeanDefinitionException(this.descriptor.getResolvableType());
}
return result;
}
}
@Override
@Nullable
public Object getObject(final Object... args) throws BeansException {
if (this.optional) {
return createOptionalDependency(this.descriptor, this.beanName, args);
@ -1635,10 +1651,14 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
DependencyDescriptor descriptorToUse = new DependencyDescriptor(descriptor) {
@Override
public Object resolveCandidate(String beanName, Class<?> requiredType, BeanFactory beanFactory) {
return ((AbstractBeanFactory) beanFactory).getBean(beanName, requiredType, args);
return beanFactory.getBean(beanName, args);
}
};
return doResolveDependency(descriptorToUse, this.beanName, null, null);
Object result = doResolveDependency(descriptorToUse, this.beanName, null, null);
if (result == null) {
throw new NoSuchBeanDefinitionException(this.descriptor.getResolvableType());
}
return result;
}
}
@ -1680,6 +1700,16 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
return doResolveDependency(descriptorToUse, this.beanName, null, null);
}
}
@Nullable
protected Object getValue() throws BeansException {
if (this.optional) {
return createOptionalDependency(this.descriptor, this.beanName);
}
else {
return doResolveDependency(this.descriptor, this.beanName, null, null);
}
}
}
@ -1695,7 +1725,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
@Override
@Nullable
public Object get() throws BeansException {
return getObject();
return getValue();
}
}

View File

@ -73,13 +73,6 @@ import org.springframework.util.StringUtils;
*/
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
/**
* Internal marker for a null singleton object:
* used as marker value for concurrent Maps (which don't support null values).
*/
protected static final Object NULL_OBJECT = new Object();
/** Logger available to subclasses */
protected final Log logger = LogFactory.getLog(getClass());
@ -125,7 +118,8 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements
@Override
public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
Assert.notNull(beanName, "'beanName' must not be null");
Assert.notNull(beanName, "Bean name must not be null");
Assert.notNull(singletonObject, "Singleton object must not be null");
synchronized (this.singletonObjects) {
Object oldObject = this.singletonObjects.get(beanName);
if (oldObject != null) {
@ -142,9 +136,9 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements
* @param beanName the name of the bean
* @param singletonObject the singleton object
*/
protected void addSingleton(String beanName, @Nullable Object singletonObject) {
protected void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
this.singletonObjects.put(beanName, (singletonObject != null ? singletonObject : NULL_OBJECT));
this.singletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
@ -200,7 +194,7 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements
}
}
}
return (singletonObject != NULL_OBJECT ? singletonObject : null);
return singletonObject;
}
/**
@ -211,9 +205,8 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements
* with, if necessary
* @return the registered singleton object
*/
@Nullable
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "'beanName' must not be null");
Assert.notNull(beanName, "Bean name must not be null");
synchronized (this.singletonObjects) {
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
@ -261,7 +254,7 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements
addSingleton(beanName, singletonObject);
}
}
return (singletonObject != NULL_OBJECT ? singletonObject : null);
return singletonObject;
}
}

View File

@ -81,8 +81,7 @@ public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanReg
*/
@Nullable
protected Object getCachedObjectForFactoryBean(String beanName) {
Object object = this.factoryBeanObjectCache.get(beanName);
return (object != NULL_OBJECT ? object : null);
return this.factoryBeanObjectCache.get(beanName);
}
/**
@ -94,7 +93,6 @@ public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanReg
* @throws BeanCreationException if FactoryBean object creation failed
* @see org.springframework.beans.factory.FactoryBean#getObject()
*/
@Nullable
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
if (factory.isSingleton() && containsSingleton(beanName)) {
synchronized (getSingletonMutex()) {
@ -108,7 +106,7 @@ public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanReg
object = alreadyThere;
}
else {
if (object != null && shouldPostProcess) {
if (shouldPostProcess) {
try {
object = postProcessObjectFromFactoryBean(object, beanName);
}
@ -117,15 +115,15 @@ public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanReg
"Post-processing of FactoryBean's singleton object failed", ex);
}
}
this.factoryBeanObjectCache.put(beanName, (object != null ? object : NULL_OBJECT));
this.factoryBeanObjectCache.put(beanName, object);
}
}
return (object != NULL_OBJECT ? object : null);
return object;
}
}
else {
Object object = doGetObjectFromFactoryBean(factory, beanName);
if (object != null && shouldPostProcess) {
if (shouldPostProcess) {
try {
object = postProcessObjectFromFactoryBean(object, beanName);
}
@ -145,7 +143,6 @@ public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanReg
* @throws BeanCreationException if FactoryBean object creation failed
* @see org.springframework.beans.factory.FactoryBean#getObject()
*/
@Nullable
private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName)
throws BeanCreationException {
@ -174,9 +171,12 @@ public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanReg
// Do not accept a null value for a FactoryBean that's not fully
// initialized yet: Many FactoryBeans just return null then.
if (object == null && isSingletonCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(
beanName, "FactoryBean which is currently in creation returned null from getObject");
if (object == null) {
if (isSingletonCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(
beanName, "FactoryBean which is currently in creation returned null from getObject");
}
object = new NullBean();
}
return object;
}
@ -191,7 +191,6 @@ public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanReg
* @return the object to expose
* @throws org.springframework.beans.BeansException if any post-processing failed
*/
@Nullable
protected Object postProcessObjectFromFactoryBean(Object object, String beanName) throws BeansException {
return object;
}

View File

@ -0,0 +1,57 @@
/*
* Copyright 2002-2017 the original author or authors.
*
* 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.springframework.beans.factory.support;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.lang.Nullable;
/**
* Internal representation of a null bean instance, e.g. for a {@code null} value
* returned from {@link FactoryBean#getObject()} or from a factory method.
*
* <p>Each such null bean is represented by a dedicated {@code NullBean} instance
* which are not equal to each other, uniquely differentiating each bean as returned
* from all variants of {@link org.springframework.beans.factory.BeanFactory#getBean}.
* However, each such instance will return {@code true} for {@code #equals(null)}
* and returns "null" from {@code #toString()}, which is how they can be tested
* externally (since this class itself is not public).
*
* @author Juergen Hoeller
* @since 5.0
*/
final class NullBean {
NullBean() {
}
@Override
public boolean equals(@Nullable Object obj) {
return (this == obj || obj == null);
}
@Override
public int hashCode() {
return NullBean.class.hashCode();
}
@Override
public String toString() {
return "null";
}
}

View File

@ -152,7 +152,11 @@ public class SimpleInstantiationStrategy implements InstantiationStrategy {
Method priorInvokedFactoryMethod = currentlyInvokedFactoryMethod.get();
try {
currentlyInvokedFactoryMethod.set(factoryMethod);
return factoryMethod.invoke(factoryBean, args);
Object result = factoryMethod.invoke(factoryBean, args);
if (result == null) {
result = new NullBean();
}
return result;
}
finally {
if (priorInvokedFactoryMethod != null) {

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -51,8 +51,8 @@ public class FactoryBeanTests {
public void testFactoryBeanReturnsNull() throws Exception {
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
new XmlBeanDefinitionReader(factory).loadBeanDefinitions(RETURNS_NULL_CONTEXT);
Object result = factory.getBean("factoryBean");
assertNull(result);
assertEquals("null", factory.getBean("factoryBean").toString());
}
@Test

View File

@ -572,8 +572,9 @@ public class AutowiredAnnotationBeanPostProcessorTests {
}
@Test
public void testConstructorResourceInjectionWithNull() {
public void testConstructorResourceInjectionWithNullFromFactoryBean() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
bf.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver());
bf.registerResolvableDependency(BeanFactory.class, bf);
AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
bpp.setBeanFactory(bf);
@ -603,6 +604,42 @@ public class AutowiredAnnotationBeanPostProcessorTests {
assertSame(bf, bean.getBeanFactory());
}
@Test
public void testConstructorResourceInjectionWithNullFromFactoryMethod() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
bf.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver());
bf.registerResolvableDependency(BeanFactory.class, bf);
AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
bpp.setBeanFactory(bf);
bf.addBeanPostProcessor(bpp);
RootBeanDefinition bd = new RootBeanDefinition(ConstructorResourceInjectionBean.class);
bd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
bf.registerBeanDefinition("annotatedBean", bd);
RootBeanDefinition tb = new RootBeanDefinition(NullFactoryMethods.class);
tb.setFactoryMethodName("createTestBean");
bf.registerBeanDefinition("testBean", tb);
RootBeanDefinition ntb = new RootBeanDefinition(NullFactoryMethods.class);
ntb.setFactoryMethodName("createNestedTestBean");
bf.registerBeanDefinition("nestedTestBean", ntb);
bf.registerSingleton("nestedTestBean2", new NestedTestBean());
ConstructorResourceInjectionBean bean = (ConstructorResourceInjectionBean) bf.getBean("annotatedBean");
assertNull(bean.getTestBean());
assertNull(bean.getTestBean2());
assertNull(bean.getTestBean3());
assertNull(bean.getTestBean4());
assertNull(bean.getNestedTestBean());
assertSame(bf, bean.getBeanFactory());
bean = (ConstructorResourceInjectionBean) bf.getBean("annotatedBean");
assertNull(bean.getTestBean());
assertNull(bean.getTestBean2());
assertNull(bean.getTestBean3());
assertNull(bean.getTestBean4());
assertNull(bean.getNestedTestBean());
assertSame(bf, bean.getBeanFactory());
}
@Test
public void testConstructorResourceInjectionWithMultipleCandidates() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
@ -756,6 +793,33 @@ public class AutowiredAnnotationBeanPostProcessorTests {
bf.destroySingletons();
}
@Test(expected = UnsatisfiedDependencyException.class)
public void testSingleConstructorInjectionWithMissingDependency() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
bf.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver());
AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
bpp.setBeanFactory(bf);
bf.addBeanPostProcessor(bpp);
bf.registerBeanDefinition("annotatedBean", new RootBeanDefinition(SingleConstructorCollectionInjectionBean.class));
bf.getBean("annotatedBean");
}
@Test(expected = UnsatisfiedDependencyException.class)
public void testSingleConstructorInjectionWithNullDependency() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
bf.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver());
AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
bpp.setBeanFactory(bf);
bf.addBeanPostProcessor(bpp);
bf.registerBeanDefinition("annotatedBean", new RootBeanDefinition(SingleConstructorCollectionInjectionBean.class));
RootBeanDefinition tb = new RootBeanDefinition(NullFactoryMethods.class);
tb.setFactoryMethodName("createTestBean");
bf.registerBeanDefinition("testBean", tb);
bf.getBean("annotatedBean");
}
@Test
public void testConstructorResourceInjectionWithMultipleCandidatesAndFallback() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
@ -2634,7 +2698,7 @@ public class AutowiredAnnotationBeanPostProcessorTests {
public static class ConstructorResourceInjectionBean extends ResourceInjectionBean {
@Autowired
@Autowired(required = false)
protected ITestBean testBean3;
private ITestBean testBean4;
@ -2643,7 +2707,6 @@ public class AutowiredAnnotationBeanPostProcessorTests {
private ConfigurableListableBeanFactory beanFactory;
public ConstructorResourceInjectionBean() {
throw new UnsupportedOperationException();
}
@ -2653,7 +2716,8 @@ public class AutowiredAnnotationBeanPostProcessorTests {
}
@Autowired
public ConstructorResourceInjectionBean(ITestBean testBean4, NestedTestBean nestedTestBean,
public ConstructorResourceInjectionBean(@Autowired(required = false) ITestBean testBean4,
@Autowired(required = false) NestedTestBean nestedTestBean,
ConfigurableListableBeanFactory beanFactory) {
this.testBean4 = testBean4;
this.nestedTestBean = nestedTestBean;
@ -2669,7 +2733,7 @@ public class AutowiredAnnotationBeanPostProcessorTests {
}
@Override
@Autowired
@Autowired(required = false)
public void setTestBean2(TestBean testBean2) {
super.setTestBean2(testBean2);
}
@ -3802,6 +3866,18 @@ public class AutowiredAnnotationBeanPostProcessorTests {
}
public static class NullFactoryMethods {
public static TestBean createTestBean() {
return null;
}
public static NestedTestBean createNestedTestBean() {
return null;
}
}
public static class ProvidedArgumentBean {
public ProvidedArgumentBean(String[] args) {

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -38,6 +38,7 @@ public class PropertyPathFactoryBeanTests {
private static final Resource CONTEXT = qualifiedResource(PropertyPathFactoryBeanTests.class, "context.xml");
@Test
public void testPropertyPathFactoryBeanWithSingletonResult() {
DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
@ -78,7 +79,7 @@ public class PropertyPathFactoryBeanTests {
DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
new XmlBeanDefinitionReader(xbf).loadBeanDefinitions(CONTEXT);
assertNull(xbf.getType("tb.spouse.spouse"));
assertNull(xbf.getBean("tb.spouse.spouse"));
assertEquals("null", xbf.getBean("tb.spouse.spouse").toString());
}
@Test
@ -92,4 +93,18 @@ public class PropertyPathFactoryBeanTests {
assertSame(spouse, tbWithInner.getFriends().iterator().next());
}
@Test
public void testPropertyPathFactoryBeanAsNullReference() {
DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
new XmlBeanDefinitionReader(xbf).loadBeanDefinitions(CONTEXT);
assertNull(xbf.getBean("tbWithNullReference", TestBean.class).getSpouse());
}
@Test
public void testPropertyPathFactoryBeanAsInnerNull() {
DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
new XmlBeanDefinitionReader(xbf).loadBeanDefinitions(CONTEXT);
assertNull(xbf.getBean("tbWithInnerNull", TestBean.class).getSpouse());
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2014 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -91,8 +91,7 @@ public class FactoryMethodTests {
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(xbf);
reader.loadBeanDefinitions(new ClassPathResource("factory-methods.xml", getClass()));
FactoryMethods fm = (FactoryMethods) xbf.getBean("null");
assertNull(fm);
assertEquals("null", xbf.getBean("null").toString());
try {
xbf.getBean("nullWithProperty");

View File

@ -57,6 +57,16 @@
<property name="friends">
<bean name="otb.spouse" class="org.springframework.beans.factory.config.PropertyPathFactoryBean"/>
</property>
</bean>
</bean>
<bean id="tbWithNullReference" class="org.springframework.tests.sample.beans.TestBean">
<property name="spouse" ref="tb.spouse.spouse"/>
</bean>
<bean id="tbWithInnerNull" class="org.springframework.tests.sample.beans.TestBean">
<property name="spouse">
<bean name="tb.spouse.spouse" class="org.springframework.beans.factory.config.PropertyPathFactoryBean"/>
</property>
</bean>
</beans>

View File

@ -18,6 +18,8 @@ package org.springframework.cache.support;
import java.io.Serializable;
import org.springframework.lang.Nullable;
/**
* Simple serializable class that serves as a {@code null} replacement
* for cache stores which otherwise do not support {@code null} values.
@ -46,4 +48,20 @@ public final class NullValue implements Serializable {
return INSTANCE;
}
@Override
public boolean equals(@Nullable Object obj) {
return (this == obj || obj == null);
}
@Override
public int hashCode() {
return NullValue.class.hashCode();
}
@Override
public String toString() {
return "null";
}
}

View File

@ -72,7 +72,6 @@ public class SimpleThreadScope implements Scope {
Object scopedObject = scope.get(name);
if (scopedObject == null) {
scopedObject = objectFactory.getObject();
Assert.state(scopedObject != null, "Scoped object resolved to null");
scope.put(name, scopedObject);
}
return scopedObject;

View File

@ -508,7 +508,7 @@ public class MBeanExporter extends MBeanRegistrationSupport implements MBeanExpo
//---------------------------------------------------------------------
/**
* Registers the defined beans with the {@link MBeanServer}.
* Register the defined beans with the {@link MBeanServer}.
* <p>Each bean is exposed to the {@code MBeanServer} via a
* {@code ModelMBean}. The actual implemetation of the
* {@code ModelMBean} interface used depends on the implementation of
@ -566,7 +566,7 @@ public class MBeanExporter extends MBeanRegistrationSupport implements MBeanExpo
}
/**
* Registers an individual bean with the {@link #setServer MBeanServer}.
* Register an individual bean with the {@link #setServer MBeanServer}.
* <p>This method is responsible for deciding <strong>how</strong> a bean
* should be exposed to the {@code MBeanServer}. Specifically, if the
* supplied {@code mapValue} is the name of a bean that is configured
@ -579,15 +579,13 @@ public class MBeanExporter extends MBeanRegistrationSupport implements MBeanExpo
* @param mapValue the value configured for this bean in the beans map;
* may be either the {@code String} name of a bean, or the bean itself
* @param beanKey the key associated with this bean in the beans map
* @return the {@code ObjectName} under which the resource was registered,
* or {@code null} if the actual resource was {@code null} as well
* @return the {@code ObjectName} under which the resource was registered
* @throws MBeanExportException if the export failed
* @see #setBeans
* @see #registerBeanInstance
* @see #registerLazyInit
*/
@Nullable
protected ObjectName registerBeanNameOrInstance(@Nullable Object mapValue, String beanKey) throws MBeanExportException {
protected ObjectName registerBeanNameOrInstance(Object mapValue, String beanKey) throws MBeanExportException {
try {
if (mapValue instanceof String) {
// Bean name pointing to a potentially lazy-init bean in the factory.
@ -607,7 +605,7 @@ public class MBeanExporter extends MBeanRegistrationSupport implements MBeanExpo
return objectName;
}
}
else if (mapValue != null) {
else {
// Plain bean instance -> register it directly.
if (this.beanFactory != null) {
Map<String, ?> beansOfSameType =
@ -623,9 +621,6 @@ public class MBeanExporter extends MBeanRegistrationSupport implements MBeanExpo
}
return registerBeanInstance(mapValue, beanKey);
}
else {
return null;
}
}
catch (Throwable ex) {
throw new UnableToRegisterMBeanException(
@ -634,14 +629,14 @@ public class MBeanExporter extends MBeanRegistrationSupport implements MBeanExpo
}
/**
* Replaces any bean names used as keys in the {@code NotificationListener}
* Replace any bean names used as keys in the {@code NotificationListener}
* mappings with their corresponding {@code ObjectName} values.
* @param beanName the name of the bean to be registered
* @param objectName the {@code ObjectName} under which the bean will be registered
* with the {@code MBeanServer}
*/
private void replaceNotificationListenerBeanNameKeysIfNecessary(String beanName, @Nullable ObjectName objectName) {
if (objectName != null && this.notificationListeners != null) {
private void replaceNotificationListenerBeanNameKeysIfNecessary(String beanName, ObjectName objectName) {
if (this.notificationListeners != null) {
for (NotificationListenerBean notificationListener : this.notificationListeners) {
notificationListener.replaceObjectName(beanName, objectName);
}
@ -656,12 +651,7 @@ public class MBeanExporter extends MBeanRegistrationSupport implements MBeanExpo
* @return the {@code ObjectName} under which the bean was registered
* with the {@code MBeanServer}
*/
@Nullable
private ObjectName registerBeanInstance(@Nullable Object bean, String beanKey) throws JMException {
if (bean == null) {
return null;
}
private ObjectName registerBeanInstance(Object bean, String beanKey) throws JMException {
ObjectName objectName = getObjectName(bean, beanKey);
Object mbeanToExpose = null;
if (isMBean(bean.getClass())) {
@ -695,7 +685,7 @@ public class MBeanExporter extends MBeanRegistrationSupport implements MBeanExpo
}
/**
* Registers beans that are configured for lazy initialization with the
* Register beans that are configured for lazy initialization with the
* {@code MBeanServer} indirectly through a proxy.
* @param beanName the name of the bean in the {@code BeanFactory}
* @param beanKey the key associated with this bean in the beans map
@ -890,7 +880,13 @@ public class MBeanExporter extends MBeanRegistrationSupport implements MBeanExpo
Class<?> beanClass = this.beanFactory.getType(beanName);
if (beanClass != null && callback.include(beanClass, beanName)) {
boolean lazyInit = isBeanDefinitionLazyInit(this.beanFactory, beanName);
Object beanInstance = (!lazyInit ? this.beanFactory.getBean(beanName) : null);
Object beanInstance = null;
if (!lazyInit) {
beanInstance = this.beanFactory.getBean(beanName);
if (!beanClass.isInstance(beanInstance)) {
continue;
}
}
if (!ScopedProxyUtils.isScopedTarget(beanName) && !beans.containsValue(beanName) &&
(beanInstance == null ||
!CollectionUtils.containsInstance(beans.values(), beanInstance))) {

View File

@ -58,14 +58,14 @@ public class CacheResolverCustomizationTests {
@Before
public void setUp() {
public void setup() {
ApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
this.cacheManager = context.getBean("cacheManager", CacheManager.class);
this.anotherCacheManager = context.getBean("anotherCacheManager", CacheManager.class);
this.simpleService = context.getBean(SimpleService.class);
}
@Test
public void noCustomization() {
Cache cache = this.cacheManager.getCache("default");
@ -162,12 +162,6 @@ public class CacheResolverCustomizationTests {
return CacheTestUtils.createSimpleCacheManager("default", "primary", "secondary");
}
@Override
@Bean
public KeyGenerator keyGenerator() {
return null;
}
@Bean
public CacheManager anotherCacheManager() {
return CacheTestUtils.createSimpleCacheManager("default", "primary", "secondary");

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -114,7 +114,7 @@ public class CommonAnnotationBeanPostProcessorTests {
rbd.setFactoryMethodName("create");
bf.registerBeanDefinition("bean", rbd);
assertNull(bf.getBean("bean"));
assertEquals("null", bf.getBean("bean").toString());
bf.destroySingletons();
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -30,13 +30,6 @@ import static org.junit.Assert.*;
*/
public class GenericApplicationContextTests {
@Test
public void nullBeanRegistration() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
bf.registerSingleton("nullBean", null);
new GenericApplicationContext(bf).refresh();
}
@Test
public void getBeanForClass() {
GenericApplicationContext ac = new GenericApplicationContext();

View File

@ -19,7 +19,6 @@ package org.springframework.messaging.simp;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.config.Scope;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
* A {@link Scope} implementation exposing the attributes of a SiMP session
@ -44,7 +43,6 @@ public class SimpSessionScope implements Scope {
scopedObject = simpAttributes.getAttribute(name);
if (scopedObject == null) {
scopedObject = objectFactory.getObject();
Assert.state(scopedObject != null, "Scoped object resolved to null");
simpAttributes.setAttribute(name, scopedObject);
}
return scopedObject;

View File

@ -54,7 +54,6 @@ public class SimpleTransactionScope implements Scope {
Object scopedObject = scopedObjects.scopedInstances.get(name);
if (scopedObject == null) {
scopedObject = objectFactory.getObject();
Assert.state(scopedObject != null, "Scoped object resolved to null");
scopedObjects.scopedInstances.put(name, scopedObject);
}
return scopedObject;

View File

@ -19,7 +19,6 @@ package org.springframework.web.context.request;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.config.Scope;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
* Abstract {@link Scope} implementation that reads from a particular scope
@ -44,7 +43,6 @@ public abstract class AbstractRequestAttributesScope implements Scope {
Object scopedObject = attributes.getAttribute(name, getScope());
if (scopedObject == null) {
scopedObject = objectFactory.getObject();
Assert.state(scopedObject != null, "Scoped object resolved to null");
attributes.setAttribute(name, scopedObject, getScope());
// Retrieve object again, registering it for implicit session attribute updates.
// As a bonus, we also allow for potential decoration at the getAttribute level.

View File

@ -68,7 +68,6 @@ public class ServletContextScope implements Scope, DisposableBean {
Object scopedObject = this.servletContext.getAttribute(name);
if (scopedObject == null) {
scopedObject = objectFactory.getObject();
Assert.state(scopedObject != null, "Scoped object resolved to null");
this.servletContext.setAttribute(name, scopedObject);
}
return scopedObject;