SmartObjectFactory provides getObject(args) variant as well
Issue: SPR-13956
This commit is contained in:
@@ -28,8 +28,20 @@ import org.springframework.beans.BeansException;
|
||||
public interface SmartObjectFactory<T> extends ObjectFactory<T> {
|
||||
|
||||
/**
|
||||
* Return an instance (possibly shared or independent)
|
||||
* of the object managed by this factory.
|
||||
* Return an instance (possibly shared or independent) of the object
|
||||
* managed by this factory.
|
||||
* <p>Allows for specifying explicit construction arguments, along the
|
||||
* lines of {@link BeanFactory#getBean(String, Object...)}.
|
||||
* @param args arguments to use when creating a corresponding instance
|
||||
* @return an instance of the bean
|
||||
* @throws BeansException in case of creation errors
|
||||
* @see #getObject()
|
||||
*/
|
||||
T getObject(Object... args) throws BeansException;
|
||||
|
||||
/**
|
||||
* Return an instance (possibly shared or independent) of the object
|
||||
* managed by this factory.
|
||||
* @return an instance of the bean, or {@code null} if not available
|
||||
* @throws BeansException in case of creation errors
|
||||
* @see #getObject()
|
||||
@@ -37,8 +49,8 @@ public interface SmartObjectFactory<T> extends ObjectFactory<T> {
|
||||
T getIfAvailable() throws BeansException;
|
||||
|
||||
/**
|
||||
* Return an instance (possibly shared or independent)
|
||||
* of the object managed by this factory.
|
||||
* Return an instance (possibly shared or independent) of the object
|
||||
* managed by this factory.
|
||||
* @return an instance of the bean, or {@code null} if not available or
|
||||
* not unique (i.e. multiple candidates found with none marked as primary)
|
||||
* @throws BeansException in case of creation errors
|
||||
|
||||
@@ -26,6 +26,7 @@ import java.lang.reflect.Type;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.NoUniqueBeanDefinitionException;
|
||||
import org.springframework.core.GenericCollectionTypeResolver;
|
||||
import org.springframework.core.GenericTypeResolver;
|
||||
@@ -200,6 +201,20 @@ public class DependencyDescriptor implements Serializable {
|
||||
throw new NoUniqueBeanDefinitionException(type, matchingBeans.keySet());
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve the specified bean name, as a candidate result of the matching
|
||||
* algorithm for this dependency, to a bean instance from the given factory.
|
||||
* <p>The default implementation calls {@link BeanFactory#getBean(String)}.
|
||||
* Subclasses may provide additional arguments or other customizations.
|
||||
* @param beanName the bean name, as a candidate result for this dependency
|
||||
* @param beanFactory the associated factory
|
||||
* @return the bean instance (never {@code null})
|
||||
* @see BeanFactory#getBean(String)
|
||||
*/
|
||||
public Object resolveCandidate(String beanName, BeanFactory beanFactory) {
|
||||
return beanFactory.getBean(beanName);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Increase this descriptor's nesting level.
|
||||
|
||||
@@ -1052,7 +1052,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
if (matchingBeans.size() > 1) {
|
||||
String primaryBeanName = determineAutowireCandidate(matchingBeans, descriptor);
|
||||
if (primaryBeanName == null) {
|
||||
if (!indicatesMultipleBeans(type) || descriptor.isRequired()) {
|
||||
if (descriptor.isRequired() || !indicatesMultipleBeans(type)) {
|
||||
return descriptor.resolveNotUnique(type, matchingBeans);
|
||||
}
|
||||
else {
|
||||
@@ -1198,7 +1198,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
}
|
||||
for (String candidateName : candidateNames) {
|
||||
if (!isSelfReference(beanName, candidateName) && isAutowireCandidate(candidateName, descriptor)) {
|
||||
result.put(candidateName, getBean(candidateName));
|
||||
result.put(candidateName, descriptor.resolveCandidate(candidateName, this));
|
||||
}
|
||||
}
|
||||
if (result.isEmpty() && !indicatesMultipleBeans(requiredType)) {
|
||||
@@ -1206,14 +1206,14 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
DependencyDescriptor fallbackDescriptor = descriptor.forFallbackMatch();
|
||||
for (String candidateName : candidateNames) {
|
||||
if (!isSelfReference(beanName, candidateName) && isAutowireCandidate(candidateName, fallbackDescriptor)) {
|
||||
result.put(candidateName, getBean(candidateName));
|
||||
result.put(candidateName, descriptor.resolveCandidate(candidateName, this));
|
||||
}
|
||||
}
|
||||
if (result.isEmpty()) {
|
||||
// Consider self references before as a final pass
|
||||
for (String candidateName : candidateNames) {
|
||||
if (isSelfReference(beanName, candidateName) && isAutowireCandidate(candidateName, fallbackDescriptor)) {
|
||||
result.put(candidateName, getBean(candidateName));
|
||||
result.put(candidateName, descriptor.resolveCandidate(candidateName, this));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1462,12 +1462,17 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
@UsesJava8
|
||||
private class OptionalDependencyFactory {
|
||||
|
||||
public Object createOptionalDependency(DependencyDescriptor descriptor, String beanName) {
|
||||
public Object createOptionalDependency(DependencyDescriptor descriptor, String beanName, final Object... args) {
|
||||
DependencyDescriptor descriptorToUse = new DependencyDescriptor(descriptor) {
|
||||
@Override
|
||||
public boolean isRequired() {
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public Object resolveCandidate(String beanName, BeanFactory beanFactory) {
|
||||
return (!ObjectUtils.isEmpty(args) ? beanFactory.getBean(beanName, args) :
|
||||
super.resolveCandidate(beanName, beanFactory));
|
||||
}
|
||||
};
|
||||
descriptorToUse.increaseNestingLevel();
|
||||
return Optional.ofNullable(doResolveDependency(descriptorToUse, beanName, null, null));
|
||||
@@ -1503,6 +1508,22 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getObject(final Object... args) throws BeansException {
|
||||
if (this.optional) {
|
||||
return new OptionalDependencyFactory().createOptionalDependency(this.descriptor, this.beanName, args);
|
||||
}
|
||||
else {
|
||||
DependencyDescriptor descriptorToUse = new DependencyDescriptor(descriptor) {
|
||||
@Override
|
||||
public Object resolveCandidate(String beanName, BeanFactory beanFactory) {
|
||||
return beanFactory.getBean(beanName, args);
|
||||
}
|
||||
};
|
||||
return doResolveDependency(descriptorToUse, this.beanName, null, null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getIfAvailable() throws BeansException {
|
||||
if (this.optional) {
|
||||
|
||||
Reference in New Issue
Block a user