|
|
|
@ -396,6 +396,23 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* Resolve the specified cached method argument or field value. |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
private Object resolvedCachedArgument(String beanName, Object cachedArgument) { |
|
|
|
|
|
|
|
if (cachedArgument instanceof DependencyDescriptor) { |
|
|
|
|
|
|
|
DependencyDescriptor descriptor = (DependencyDescriptor) cachedArgument; |
|
|
|
|
|
|
|
TypeConverter typeConverter = beanFactory.getTypeConverter(); |
|
|
|
|
|
|
|
return beanFactory.resolveDependency(descriptor, beanName, null, typeConverter); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else if (cachedArgument instanceof RuntimeBeanReference) { |
|
|
|
|
|
|
|
return beanFactory.getBean(((RuntimeBeanReference) cachedArgument).getBeanName()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else { |
|
|
|
|
|
|
|
return cachedArgument; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Class representing injection information about an annotated field. |
|
|
|
* Class representing injection information about an annotated field. |
|
|
|
@ -419,39 +436,37 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean |
|
|
|
try { |
|
|
|
try { |
|
|
|
Object value; |
|
|
|
Object value; |
|
|
|
if (this.cached) { |
|
|
|
if (this.cached) { |
|
|
|
if (this.cachedFieldValue instanceof DependencyDescriptor) { |
|
|
|
value = resolvedCachedArgument(beanName, this.cachedFieldValue); |
|
|
|
DependencyDescriptor descriptor = (DependencyDescriptor) this.cachedFieldValue; |
|
|
|
|
|
|
|
TypeConverter typeConverter = beanFactory.getTypeConverter(); |
|
|
|
|
|
|
|
value = beanFactory.resolveDependency(descriptor, beanName, null, typeConverter); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else if (this.cachedFieldValue instanceof RuntimeBeanReference) { |
|
|
|
|
|
|
|
value = beanFactory.getBean(((RuntimeBeanReference) this.cachedFieldValue).getBeanName()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else { |
|
|
|
|
|
|
|
value = this.cachedFieldValue; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
else { |
|
|
|
else { |
|
|
|
Set<String> autowiredBeanNames = new LinkedHashSet<String>(1); |
|
|
|
synchronized (this) { |
|
|
|
TypeConverter typeConverter = beanFactory.getTypeConverter(); |
|
|
|
if (!this.cached) { |
|
|
|
DependencyDescriptor descriptor = new DependencyDescriptor(field, this.required); |
|
|
|
Set<String> autowiredBeanNames = new LinkedHashSet<String>(1); |
|
|
|
this.cachedFieldValue = descriptor; |
|
|
|
TypeConverter typeConverter = beanFactory.getTypeConverter(); |
|
|
|
value = beanFactory.resolveDependency(descriptor, beanName, autowiredBeanNames, typeConverter); |
|
|
|
DependencyDescriptor descriptor = new DependencyDescriptor(field, this.required); |
|
|
|
if (value != null) { |
|
|
|
this.cachedFieldValue = descriptor; |
|
|
|
registerDependentBeans(beanName, autowiredBeanNames); |
|
|
|
value = beanFactory.resolveDependency(descriptor, beanName, autowiredBeanNames, typeConverter); |
|
|
|
if (autowiredBeanNames.size() == 1) { |
|
|
|
if (value != null) { |
|
|
|
String autowiredBeanName = autowiredBeanNames.iterator().next(); |
|
|
|
registerDependentBeans(beanName, autowiredBeanNames); |
|
|
|
if (beanFactory.containsBean(autowiredBeanName)) { |
|
|
|
if (autowiredBeanNames.size() == 1) { |
|
|
|
if (beanFactory.isTypeMatch(autowiredBeanName, field.getType())) { |
|
|
|
String autowiredBeanName = autowiredBeanNames.iterator().next(); |
|
|
|
this.cachedFieldValue = new RuntimeBeanReference(autowiredBeanName); |
|
|
|
if (beanFactory.containsBean(autowiredBeanName)) { |
|
|
|
|
|
|
|
if (beanFactory.isTypeMatch(autowiredBeanName, field.getType())) { |
|
|
|
|
|
|
|
this.cachedFieldValue = new RuntimeBeanReference(autowiredBeanName); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
else { |
|
|
|
|
|
|
|
this.cachedFieldValue = null; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
this.cached = true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else { |
|
|
|
|
|
|
|
// Already cached in the meantime...
|
|
|
|
|
|
|
|
value = resolvedCachedArgument(beanName, this.cachedFieldValue); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
else { |
|
|
|
|
|
|
|
this.cachedFieldValue = null; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
this.cached = true; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
if (value != null) { |
|
|
|
if (value != null) { |
|
|
|
ReflectionUtils.makeAccessible(field); |
|
|
|
ReflectionUtils.makeAccessible(field); |
|
|
|
@ -492,65 +507,58 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean |
|
|
|
} |
|
|
|
} |
|
|
|
Method method = (Method) this.member; |
|
|
|
Method method = (Method) this.member; |
|
|
|
try { |
|
|
|
try { |
|
|
|
Object[] arguments = null; |
|
|
|
Object[] arguments; |
|
|
|
if (this.cached) { |
|
|
|
if (this.cached) { |
|
|
|
if (this.cachedMethodArguments != null) { |
|
|
|
// Shortcut for avoiding synchronization...
|
|
|
|
arguments = new Object[this.cachedMethodArguments.length]; |
|
|
|
arguments = resolveCachedArguments(beanName); |
|
|
|
for (int i = 0; i < arguments.length; i++) { |
|
|
|
|
|
|
|
Object cachedArg = this.cachedMethodArguments[i]; |
|
|
|
|
|
|
|
if (cachedArg instanceof DependencyDescriptor) { |
|
|
|
|
|
|
|
DependencyDescriptor descriptor = (DependencyDescriptor) cachedArg; |
|
|
|
|
|
|
|
TypeConverter typeConverter = beanFactory.getTypeConverter(); |
|
|
|
|
|
|
|
arguments[i] = beanFactory.resolveDependency(descriptor, beanName, null, typeConverter); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else if (cachedArg instanceof RuntimeBeanReference) { |
|
|
|
|
|
|
|
arguments[i] = beanFactory.getBean(((RuntimeBeanReference) cachedArg).getBeanName()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else { |
|
|
|
|
|
|
|
arguments[i] = cachedArg; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
else { |
|
|
|
else { |
|
|
|
Class[] paramTypes = method.getParameterTypes(); |
|
|
|
synchronized (this) { |
|
|
|
arguments = new Object[paramTypes.length]; |
|
|
|
if (!this.cached) { |
|
|
|
Set<String> autowiredBeanNames = new LinkedHashSet<String>(arguments.length); |
|
|
|
Class[] paramTypes = method.getParameterTypes(); |
|
|
|
TypeConverter typeConverter = beanFactory.getTypeConverter(); |
|
|
|
arguments = new Object[paramTypes.length]; |
|
|
|
this.cachedMethodArguments = new Object[arguments.length]; |
|
|
|
Set<String> autowiredBeanNames = new LinkedHashSet<String>(arguments.length); |
|
|
|
for (int i = 0; i < arguments.length; i++) { |
|
|
|
TypeConverter typeConverter = beanFactory.getTypeConverter(); |
|
|
|
MethodParameter methodParam = new MethodParameter(method, i); |
|
|
|
this.cachedMethodArguments = new Object[arguments.length]; |
|
|
|
GenericTypeResolver.resolveParameterType(methodParam, bean.getClass()); |
|
|
|
for (int i = 0; i < arguments.length; i++) { |
|
|
|
DependencyDescriptor descriptor = new DependencyDescriptor(methodParam, this.required); |
|
|
|
MethodParameter methodParam = new MethodParameter(method, i); |
|
|
|
this.cachedMethodArguments[i] = descriptor; |
|
|
|
GenericTypeResolver.resolveParameterType(methodParam, bean.getClass()); |
|
|
|
arguments[i] = beanFactory.resolveDependency( |
|
|
|
DependencyDescriptor descriptor = new DependencyDescriptor(methodParam, this.required); |
|
|
|
descriptor, beanName, autowiredBeanNames, typeConverter); |
|
|
|
this.cachedMethodArguments[i] = descriptor; |
|
|
|
if (arguments[i] == null) { |
|
|
|
arguments[i] = beanFactory.resolveDependency( |
|
|
|
arguments = null; |
|
|
|
descriptor, beanName, autowiredBeanNames, typeConverter); |
|
|
|
break; |
|
|
|
if (arguments[i] == null) { |
|
|
|
} |
|
|
|
arguments = null; |
|
|
|
} |
|
|
|
break; |
|
|
|
if (arguments != null) { |
|
|
|
|
|
|
|
registerDependentBeans(beanName, autowiredBeanNames); |
|
|
|
|
|
|
|
if (autowiredBeanNames.size() == paramTypes.length) { |
|
|
|
|
|
|
|
Iterator<String> it = autowiredBeanNames.iterator(); |
|
|
|
|
|
|
|
for (int i = 0; i < paramTypes.length; i++) { |
|
|
|
|
|
|
|
String autowiredBeanName = it.next(); |
|
|
|
|
|
|
|
if (beanFactory.containsBean(autowiredBeanName)) { |
|
|
|
|
|
|
|
if (beanFactory.isTypeMatch(autowiredBeanName, paramTypes[i])) { |
|
|
|
|
|
|
|
this.cachedMethodArguments[i] = new RuntimeBeanReference(autowiredBeanName); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
else { |
|
|
|
} |
|
|
|
this.cachedMethodArguments[i] = arguments[i]; |
|
|
|
if (arguments != null) { |
|
|
|
|
|
|
|
registerDependentBeans(beanName, autowiredBeanNames); |
|
|
|
|
|
|
|
if (autowiredBeanNames.size() == paramTypes.length) { |
|
|
|
|
|
|
|
Iterator<String> it = autowiredBeanNames.iterator(); |
|
|
|
|
|
|
|
for (int i = 0; i < paramTypes.length; i++) { |
|
|
|
|
|
|
|
String autowiredBeanName = it.next(); |
|
|
|
|
|
|
|
if (beanFactory.containsBean(autowiredBeanName)) { |
|
|
|
|
|
|
|
if (beanFactory.isTypeMatch(autowiredBeanName, paramTypes[i])) { |
|
|
|
|
|
|
|
this.cachedMethodArguments[i] = new RuntimeBeanReference(autowiredBeanName); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else { |
|
|
|
|
|
|
|
this.cachedMethodArguments[i] = arguments[i]; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
else { |
|
|
|
|
|
|
|
this.cachedMethodArguments = null; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
this.cached = true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else { |
|
|
|
|
|
|
|
// Already cached in the meantime...
|
|
|
|
|
|
|
|
arguments = resolveCachedArguments(beanName); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
else { |
|
|
|
|
|
|
|
this.cachedMethodArguments = null; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
this.cached = true; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
if (this.skip == null) { |
|
|
|
if (this.skip == null) { |
|
|
|
if (this.pd != null && pvs instanceof MutablePropertyValues) { |
|
|
|
if (this.pd != null && pvs instanceof MutablePropertyValues) { |
|
|
|
@ -570,6 +578,17 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean |
|
|
|
throw new BeanCreationException("Could not autowire method: " + method, ex); |
|
|
|
throw new BeanCreationException("Could not autowire method: " + method, ex); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private Object[] resolveCachedArguments(String beanName) { |
|
|
|
|
|
|
|
if (this.cachedMethodArguments == null) { |
|
|
|
|
|
|
|
return null; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
Object[] arguments = new Object[this.cachedMethodArguments.length]; |
|
|
|
|
|
|
|
for (int i = 0; i < arguments.length; i++) { |
|
|
|
|
|
|
|
arguments[i] = resolvedCachedArgument(beanName, this.cachedMethodArguments[i]); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return arguments; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|