BeanFactory accepts getBean arguments for non-prototype beans as well
Issue: SPR-12488
This commit is contained in:
parent
c5c5473d44
commit
fa0ef2d87e
|
@ -170,7 +170,8 @@ 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 bean instance using explicit arguments
|
||||
* (only applied when creating a new instance as opposed to retrieving an existing one)
|
||||
* @return an instance of the bean
|
||||
* @throws NoSuchBeanDefinitionException if there is no such bean definition
|
||||
* @throws BeanDefinitionStoreException if arguments have been given but
|
||||
|
@ -190,8 +191,8 @@ public interface BeanFactory {
|
|||
* 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 args arguments to use if creating a prototype using explicit arguments to a
|
||||
* static factory method. It is invalid to use a non-null args value in any other case.
|
||||
* @param args arguments to use when creating a bean instance using explicit arguments
|
||||
* (only applied when creating a new instance as opposed to retrieving an existing one)
|
||||
* @return an instance of the bean
|
||||
* @throws NoSuchBeanDefinitionException if there is no such bean definition
|
||||
* @throws BeanDefinitionStoreException if arguments have been given but
|
||||
|
|
|
@ -487,8 +487,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
|||
* factory method, and autowiring a constructor.
|
||||
* @param beanName the name of the bean
|
||||
* @param mbd the merged bean definition for the bean
|
||||
* @param args arguments to use if creating a prototype using explicit arguments to a
|
||||
* static factory method. This parameter must be {@code null} except in this case.
|
||||
* @param args explicit arguments to use for constructor or factory method invocation
|
||||
* @return a new instance of the bean
|
||||
* @throws BeanCreationException if the bean could not be created
|
||||
* @see #instantiateBean
|
||||
|
@ -988,8 +987,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
|||
* factory method, constructor autowiring, or simple instantiation.
|
||||
* @param beanName the name of the bean
|
||||
* @param mbd the bean definition for the bean
|
||||
* @param args arguments to use if creating a prototype using explicit arguments to a
|
||||
* static factory method. It is invalid to use a non-null args value in any other case.
|
||||
* @param args explicit arguments to use for constructor or factory method invocation
|
||||
* @return BeanWrapper for the new instance
|
||||
* @see #instantiateUsingFactoryMethod
|
||||
* @see #autowireConstructor
|
||||
|
|
|
@ -207,8 +207,8 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
|||
* Return an instance, which may be shared or independent, of the specified bean.
|
||||
* @param name the name of the bean to retrieve
|
||||
* @param requiredType the required type of the bean to retrieve
|
||||
* @param args arguments to use if creating a prototype using explicit arguments to a
|
||||
* static factory method. It is invalid to use a non-null args value in any other case.
|
||||
* @param args arguments to use when creating a bean instance using explicit arguments
|
||||
* (only applied when creating a new instance as opposed to retrieving an existing one)
|
||||
* @return an instance of the bean
|
||||
* @throws BeansException if the bean could not be created
|
||||
*/
|
||||
|
@ -220,8 +220,8 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
|||
* Return an instance, which may be shared or independent, of the specified bean.
|
||||
* @param name the name of the bean to retrieve
|
||||
* @param requiredType the required type of the bean to retrieve
|
||||
* @param args arguments to use if creating a prototype using explicit arguments to a
|
||||
* static factory method. It is invalid to use a non-null args value in any other case.
|
||||
* @param args arguments to use when creating a bean instance using explicit arguments
|
||||
* (only applied when creating a new instance as opposed to retrieving an existing one)
|
||||
* @param typeCheckOnly whether the instance is obtained for a type check,
|
||||
* not for actual use
|
||||
* @return an instance of the bean
|
||||
|
@ -1266,17 +1266,9 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
|||
protected void checkMergedBeanDefinition(RootBeanDefinition mbd, String beanName, Object[] args)
|
||||
throws BeanDefinitionStoreException {
|
||||
|
||||
// check if bean definition is not abstract
|
||||
if (mbd.isAbstract()) {
|
||||
throw new BeanIsAbstractException(beanName);
|
||||
}
|
||||
|
||||
// Check validity of the usage of the args parameter. This can
|
||||
// only be used for prototypes constructed via a factory method.
|
||||
if (args != null && !mbd.isPrototype()) {
|
||||
throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName,
|
||||
"Can only specify arguments for the getBean method when referring to a prototype bean definition");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1619,15 +1611,13 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
|||
protected abstract BeanDefinition getBeanDefinition(String beanName) throws BeansException;
|
||||
|
||||
/**
|
||||
* Create a bean instance for the given bean definition.
|
||||
* The bean definition will already have been merged with the parent
|
||||
* definition in case of a child definition.
|
||||
* <p>All the other methods in this class invoke this method, although
|
||||
* beans may be cached after being instantiated by this method. All bean
|
||||
* instantiation within this class is performed by this method.
|
||||
* Create a bean instance for the given merged bean definition (and arguments).
|
||||
* The bean definition will already have been merged with the parent definition
|
||||
* in case of a child definition.
|
||||
* <p>All bean retrieval methods delegate to this method for actual bean creation.
|
||||
* @param beanName the name of the bean
|
||||
* @param mbd the merged bean definition for the bean
|
||||
* @param args arguments to use if creating a prototype using explicit arguments
|
||||
* @param args explicit arguments to use for constructor or factory method invocation
|
||||
* @return a new instance of the bean
|
||||
* @throws BeanCreationException if the bean could not be created
|
||||
*/
|
||||
|
|
|
@ -38,6 +38,7 @@ import org.springframework.beans.factory.config.BeanDefinitionHolder;
|
|||
import org.springframework.beans.factory.support.ChildBeanDefinition;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.componentscan.simple.SimpleComponent;
|
||||
import org.springframework.core.env.StandardEnvironment;
|
||||
import org.springframework.core.io.DescriptiveResource;
|
||||
|
@ -470,7 +471,13 @@ public class ConfigurationClassPostProcessorTests {
|
|||
|
||||
@Test
|
||||
public void testPrototypeArgumentsThroughBeanMethodCall() {
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(BeanArgumentConfig.class);
|
||||
ApplicationContext ctx = new AnnotationConfigApplicationContext(BeanArgumentConfigWithPrototype.class);
|
||||
ctx.getBean(FooFactory.class).createFoo(new BarArgument());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSingletonArgumentsThroughBeanMethodCall() {
|
||||
ApplicationContext ctx = new AnnotationConfigApplicationContext(BeanArgumentConfigWithSingleton.class);
|
||||
ctx.getBean(FooFactory.class).createFoo(new BarArgument());
|
||||
}
|
||||
|
||||
|
@ -932,7 +939,7 @@ public class ConfigurationClassPostProcessorTests {
|
|||
}
|
||||
|
||||
@Configuration
|
||||
static class BeanArgumentConfig {
|
||||
static class BeanArgumentConfigWithPrototype {
|
||||
|
||||
@Bean
|
||||
@Scope("prototype")
|
||||
|
@ -951,6 +958,25 @@ public class ConfigurationClassPostProcessorTests {
|
|||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class BeanArgumentConfigWithSingleton {
|
||||
|
||||
@Bean @Lazy
|
||||
public DependingFoo foo(final BarArgument bar) {
|
||||
return new DependingFoo(bar);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public FooFactory fooFactory() {
|
||||
return new FooFactory() {
|
||||
@Override
|
||||
public DependingFoo createFoo(final BarArgument bar) {
|
||||
return foo(bar);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
static class BarArgument {
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue