Avoid stack overflow in case of chained factory-bean references to FactoryBean class
Issue: SPR-14551
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2016 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,6 +114,7 @@ public interface BeanFactory {
|
||||
*/
|
||||
String FACTORY_BEAN_PREFIX = "&";
|
||||
|
||||
|
||||
/**
|
||||
* Return an instance, which may be shared or independent, of the specified bean.
|
||||
* <p>This method allows a Spring BeanFactory to be used as a replacement for the
|
||||
@@ -151,15 +152,16 @@ public interface BeanFactory {
|
||||
|
||||
/**
|
||||
* Return the bean instance that uniquely matches the given object type, if any.
|
||||
* @param requiredType type the bean must match; can be an interface or superclass.
|
||||
* {@code null} is disallowed.
|
||||
* <p>This method goes into {@link ListableBeanFactory} by-type lookup territory
|
||||
* but may also be translated into a conventional by-name lookup based on the name
|
||||
* of the given type. For more extensive retrieval operations across sets of beans,
|
||||
* use {@link ListableBeanFactory} and/or {@link BeanFactoryUtils}.
|
||||
* @param requiredType type the bean must match; can be an interface or superclass.
|
||||
* {@code null} is disallowed.
|
||||
* @return an instance of the single bean matching the required type
|
||||
* @throws NoSuchBeanDefinitionException if no bean of the given type was found
|
||||
* @throws NoUniqueBeanDefinitionException if more than one bean of the given type was found
|
||||
* @throws BeansException if the bean could not be created
|
||||
* @since 3.0
|
||||
* @see ListableBeanFactory
|
||||
*/
|
||||
@@ -170,7 +172,7 @@ public interface BeanFactory {
|
||||
* <p>Allows for specifying explicit constructor arguments / factory method arguments,
|
||||
* overriding the specified default arguments (if any) in the bean definition.
|
||||
* @param name the name of the bean to retrieve
|
||||
* @param args arguments to use if creating a prototype using explicit arguments
|
||||
* @param args arguments to use when creating a prototype using explicit arguments
|
||||
* @return an instance of the bean
|
||||
* @throws NoSuchBeanDefinitionException if there is no such bean definition
|
||||
* @throws BeanDefinitionStoreException if arguments have been given but
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2006 the original author or authors.
|
||||
* Copyright 2002-2016 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.
|
||||
@@ -17,10 +17,10 @@
|
||||
package org.springframework.beans.factory;
|
||||
|
||||
/**
|
||||
* Counterpart of BeanNameAware. Returns the bean name of an object.
|
||||
* Counterpart of {@link BeanNameAware}. Returns the bean name of an object.
|
||||
*
|
||||
* <p>This interface can be introduced to avoid a brittle dependence
|
||||
* on bean name in objects used with Spring IoC and Spring AOP.
|
||||
* <p>This interface can be introduced to avoid a brittle dependence on
|
||||
* bean name in objects used with Spring IoC and Spring AOP.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @since 2.0
|
||||
@@ -29,7 +29,7 @@ package org.springframework.beans.factory;
|
||||
public interface NamedBean {
|
||||
|
||||
/**
|
||||
* Return the name of this bean in a Spring bean factory.
|
||||
* Return the name of this bean in a Spring bean factory, if known.
|
||||
*/
|
||||
String getBeanName();
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2016 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,9 +114,9 @@ public interface AutowireCapableBeanFactory extends BeanFactory {
|
||||
* <p>Performs full initialization of the bean, including all applicable
|
||||
* {@link BeanPostProcessor BeanPostProcessors}.
|
||||
* <p>Note: This is intended for creating a fresh instance, populating annotated
|
||||
* fields and methods as well as applying all standard bean initialiation callbacks.
|
||||
* fields and methods as well as applying all standard bean initialization callbacks.
|
||||
* It does <i>not</> imply traditional by-name or by-type autowiring of properties;
|
||||
* use {@link #createBean(Class, int, boolean)} for that purposes.
|
||||
* use {@link #createBean(Class, int, boolean)} for those purposes.
|
||||
* @param beanClass the class of the bean to create
|
||||
* @return the new bean instance
|
||||
* @throws BeansException if instantiation or wiring failed
|
||||
@@ -129,7 +129,7 @@ public interface AutowireCapableBeanFactory extends BeanFactory {
|
||||
* <p>Note: This is essentially intended for (re-)populating annotated fields and
|
||||
* methods, either for new instances or for deserialized instances. It does
|
||||
* <i>not</i> imply traditional by-name or by-type autowiring of properties;
|
||||
* use {@link #autowireBeanProperties} for that purposes.
|
||||
* use {@link #autowireBeanProperties} for those purposes.
|
||||
* @param existingBean the existing bean instance
|
||||
* @throws BeansException if wiring failed
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2016 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.
|
||||
@@ -425,9 +425,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
* @see #doCreateBean
|
||||
*/
|
||||
@Override
|
||||
protected Object createBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
|
||||
throws BeanCreationException {
|
||||
|
||||
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Creating instance of bean '" + beanName + "'");
|
||||
}
|
||||
@@ -596,7 +594,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the bean type for the given bean definition which is based on
|
||||
* Determine the target type for the given bean definition which is based on
|
||||
* a factory method. Only called if there is no singleton instance registered
|
||||
* for the target bean already.
|
||||
* <p>This implementation determines the type matching {@link #createBean}'s
|
||||
@@ -606,7 +604,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
* @param mbd the merged bean definition for the bean
|
||||
* @param typesToMatch the types to match in case of internal type matching purposes
|
||||
* (also signals that the returned {@code Class} will never be exposed to application code)
|
||||
* @return the type for the bean if determinable, or {@code null} else
|
||||
* @return the type for the bean if determinable, or {@code null} otherwise
|
||||
* @see #createBean
|
||||
*/
|
||||
protected Class<?> getTypeForFactoryMethod(String beanName, RootBeanDefinition mbd, Class[] typesToMatch) {
|
||||
@@ -745,10 +743,14 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
if (objectType.value != null) {
|
||||
return objectType.value;
|
||||
}
|
||||
else {
|
||||
// No type found for shortcut FactoryBean instance:
|
||||
// fall back to full creation of the FactoryBean instance.
|
||||
return super.getTypeForFactoryBean(beanName, mbd);
|
||||
}
|
||||
}
|
||||
|
||||
// No type found - fall back to full creation of the FactoryBean instance.
|
||||
return super.getTypeForFactoryBean(beanName, mbd);
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -767,7 +769,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
|
||||
exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
|
||||
if (exposedObject == null) {
|
||||
return exposedObject;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -782,8 +784,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
|
||||
/**
|
||||
* Obtain a "shortcut" singleton FactoryBean instance to use for a
|
||||
* {@code getObjectType()} call, without full initialization
|
||||
* of the FactoryBean.
|
||||
* {@code getObjectType()} call, without full initialization of the FactoryBean.
|
||||
* @param beanName the name of the bean
|
||||
* @param mbd the bean definition for the bean
|
||||
* @return the FactoryBean instance, or {@code null} to indicate
|
||||
@@ -824,8 +825,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
|
||||
/**
|
||||
* Obtain a "shortcut" non-singleton FactoryBean instance to use for a
|
||||
* {@code getObjectType()} call, without full initialization
|
||||
* of the FactoryBean.
|
||||
* {@code getObjectType()} call, without full initialization of the FactoryBean.
|
||||
* @param beanName the name of the bean
|
||||
* @param mbd the bean definition for the bean
|
||||
* @return the FactoryBean instance, or {@code null} to indicate
|
||||
|
||||
Reference in New Issue
Block a user