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,
|
* <p>Allows for specifying explicit constructor arguments / factory method arguments,
|
||||||
* overriding the specified default arguments (if any) in the bean definition.
|
* overriding the specified default arguments (if any) in the bean definition.
|
||||||
* @param name the name of the bean to retrieve
|
* @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
|
* @return an instance of the bean
|
||||||
* @throws NoSuchBeanDefinitionException if there is no such bean definition
|
* @throws NoSuchBeanDefinitionException if there is no such bean definition
|
||||||
* @throws BeanDefinitionStoreException if arguments have been given but
|
* @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
|
* 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,
|
* of the given type. For more extensive retrieval operations across sets of beans,
|
||||||
* use {@link ListableBeanFactory} and/or {@link BeanFactoryUtils}.
|
* use {@link ListableBeanFactory} and/or {@link BeanFactoryUtils}.
|
||||||
* @param args arguments to use if creating a prototype using explicit arguments to a
|
* @param args arguments to use when creating a bean instance using explicit arguments
|
||||||
* static factory method. It is invalid to use a non-null args value in any other case.
|
* (only applied when creating a new instance as opposed to retrieving an existing one)
|
||||||
* @return an instance of the bean
|
* @return an instance of the bean
|
||||||
* @throws NoSuchBeanDefinitionException if there is no such bean definition
|
* @throws NoSuchBeanDefinitionException if there is no such bean definition
|
||||||
* @throws BeanDefinitionStoreException if arguments have been given but
|
* @throws BeanDefinitionStoreException if arguments have been given but
|
||||||
|
|
|
@ -487,8 +487,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||||
* factory method, and autowiring a constructor.
|
* factory method, and autowiring a constructor.
|
||||||
* @param beanName the name of the bean
|
* @param beanName the name of the bean
|
||||||
* @param mbd the merged bean definition for 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
|
* @param args explicit arguments to use for constructor or factory method invocation
|
||||||
* static factory method. This parameter must be {@code null} except in this case.
|
|
||||||
* @return a new instance of the bean
|
* @return a new instance of the bean
|
||||||
* @throws BeanCreationException if the bean could not be created
|
* @throws BeanCreationException if the bean could not be created
|
||||||
* @see #instantiateBean
|
* @see #instantiateBean
|
||||||
|
@ -988,8 +987,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||||
* factory method, constructor autowiring, or simple instantiation.
|
* factory method, constructor autowiring, or simple instantiation.
|
||||||
* @param beanName the name of the bean
|
* @param beanName the name of the bean
|
||||||
* @param mbd the bean definition for the bean
|
* @param mbd the bean definition for the bean
|
||||||
* @param args arguments to use if creating a prototype using explicit arguments to a
|
* @param args explicit arguments to use for constructor or factory method invocation
|
||||||
* static factory method. It is invalid to use a non-null args value in any other case.
|
|
||||||
* @return BeanWrapper for the new instance
|
* @return BeanWrapper for the new instance
|
||||||
* @see #instantiateUsingFactoryMethod
|
* @see #instantiateUsingFactoryMethod
|
||||||
* @see #autowireConstructor
|
* @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.
|
* Return an instance, which may be shared or independent, of the specified bean.
|
||||||
* @param name the name of the bean to retrieve
|
* @param name the name of the bean to retrieve
|
||||||
* @param requiredType the required type 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
|
* @param args arguments to use when creating a bean instance using explicit arguments
|
||||||
* static factory method. It is invalid to use a non-null args value in any other case.
|
* (only applied when creating a new instance as opposed to retrieving an existing one)
|
||||||
* @return an instance of the bean
|
* @return an instance of the bean
|
||||||
* @throws BeansException if the bean could not be created
|
* @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.
|
* Return an instance, which may be shared or independent, of the specified bean.
|
||||||
* @param name the name of the bean to retrieve
|
* @param name the name of the bean to retrieve
|
||||||
* @param requiredType the required type 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
|
* @param args arguments to use when creating a bean instance using explicit arguments
|
||||||
* static factory method. It is invalid to use a non-null args value in any other case.
|
* (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,
|
* @param typeCheckOnly whether the instance is obtained for a type check,
|
||||||
* not for actual use
|
* not for actual use
|
||||||
* @return an instance of the bean
|
* @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)
|
protected void checkMergedBeanDefinition(RootBeanDefinition mbd, String beanName, Object[] args)
|
||||||
throws BeanDefinitionStoreException {
|
throws BeanDefinitionStoreException {
|
||||||
|
|
||||||
// check if bean definition is not abstract
|
|
||||||
if (mbd.isAbstract()) {
|
if (mbd.isAbstract()) {
|
||||||
throw new BeanIsAbstractException(beanName);
|
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;
|
protected abstract BeanDefinition getBeanDefinition(String beanName) throws BeansException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a bean instance for the given bean definition.
|
* Create a bean instance for the given merged bean definition (and arguments).
|
||||||
* The bean definition will already have been merged with the parent
|
* The bean definition will already have been merged with the parent definition
|
||||||
* definition in case of a child definition.
|
* in case of a child definition.
|
||||||
* <p>All the other methods in this class invoke this method, although
|
* <p>All bean retrieval methods delegate to this method for actual bean creation.
|
||||||
* beans may be cached after being instantiated by this method. All bean
|
|
||||||
* instantiation within this class is performed by this method.
|
|
||||||
* @param beanName the name of the bean
|
* @param beanName the name of the bean
|
||||||
* @param mbd the merged bean definition for 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
|
* @return a new instance of the bean
|
||||||
* @throws BeanCreationException if the bean could not be created
|
* @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.ChildBeanDefinition;
|
||||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
import org.springframework.context.annotation.componentscan.simple.SimpleComponent;
|
import org.springframework.context.annotation.componentscan.simple.SimpleComponent;
|
||||||
import org.springframework.core.env.StandardEnvironment;
|
import org.springframework.core.env.StandardEnvironment;
|
||||||
import org.springframework.core.io.DescriptiveResource;
|
import org.springframework.core.io.DescriptiveResource;
|
||||||
|
@ -470,7 +471,13 @@ public class ConfigurationClassPostProcessorTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPrototypeArgumentsThroughBeanMethodCall() {
|
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());
|
ctx.getBean(FooFactory.class).createFoo(new BarArgument());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -932,7 +939,7 @@ public class ConfigurationClassPostProcessorTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
static class BeanArgumentConfig {
|
static class BeanArgumentConfigWithPrototype {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@Scope("prototype")
|
@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 {
|
static class BarArgument {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue