Support for Java 8's java.util.Optional at injection points

Issue: SPR-11833
This commit is contained in:
Juergen Hoeller
2014-06-06 14:41:01 +02:00
parent 6aa9c40552
commit 7d03daf8cb
2 changed files with 115 additions and 1 deletions

View File

@@ -36,6 +36,7 @@ import java.util.IdentityHashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import javax.inject.Provider;
@@ -108,6 +109,8 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
private static Class<?> javaxInjectProviderClass = null;
private static Class<?> javaUtilOptionalClass = null;
static {
try {
javaxInjectProviderClass =
@@ -116,6 +119,13 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
catch (ClassNotFoundException ex) {
// JSR-330 API not available - Provider interface simply not supported then.
}
try {
javaUtilOptionalClass =
ClassUtils.forName("java.util.Optional", DefaultListableBeanFactory.class.getClassLoader());
}
catch (ClassNotFoundException ex) {
// Java 8 not available - Optional references simply not supported then.
}
}
@@ -854,6 +864,9 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
else if (descriptor.getDependencyType().equals(javaxInjectProviderClass)) {
return new DependencyProviderFactory().createDependencyProvider(descriptor, beanName);
}
else if (descriptor.getDependencyType().equals(javaUtilOptionalClass)) {
return new OptionalDependencyFactory().createOptionalDependency(descriptor, beanName);
}
else {
Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(descriptor, beanName);
if (result == null) {
@@ -1319,4 +1332,22 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
}
}
/**
* Separate inner class for avoiding a hard dependency on the {@code javax.inject} API.
*/
private class OptionalDependencyFactory {
public Object createOptionalDependency(DependencyDescriptor descriptor, String beanName) {
DependencyDescriptor descriptorToUse = new DependencyDescriptor(descriptor) {
@Override
public boolean isRequired() {
return false;
}
};
descriptorToUse.increaseNestingLevel();
return Optional.ofNullable(doResolveDependency(descriptorToUse, beanName, null, null));
}
}
}