Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: spring-projects/spring-framework
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v5.2.12.RELEASE
Choose a base ref
...
head repository: spring-projects/spring-framework
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v5.2.13.RELEASE
Choose a head ref

Commits on Dec 9, 2020

  1. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    1764780 View commit details

Commits on Dec 10, 2020

  1. Defensively handle loadClass null result in BeanUtils.findEditorByCon…

    …vention
    
    Closes gh-26252
    
    (cherry picked from commit 2a47751)
    jhoeller committed Dec 10, 2020
    Copy the full SHA
    cfdceae View commit details

Commits on Dec 15, 2020

  1. Fix NPE when calling NettyHeadersAdapter.add()

    Prior to this commit, the `NettyHeadersAdapter` would directly delegate
    the `add()` and `set()` calls to the adapted
    `io.netty.handler.codec.http.HttpHeaders`. This implementation rejects
    `null` values with exceptions.
    
    This commit aligns the behavior here with other implementations, by not
    rejecting null values but simply ignoring them.
    
    Fixes gh-26277
    (cherry-picked from commit 83c19cd)
    bclozel committed Dec 15, 2020
    Copy the full SHA
    fe26b7d View commit details

Commits on Dec 17, 2020

  1. Consistent declarations and assertions in MockMultipartFile

    See gh-26261
    
    (cherry picked from commit fbd2ffd)
    jhoeller committed Dec 17, 2020
    Copy the full SHA
    7325a86 View commit details
  2. Polishing

    jhoeller committed Dec 17, 2020
    Copy the full SHA
    f011e58 View commit details
  3. Copy the full SHA
    eb3811e View commit details

Commits on Dec 19, 2020

  1. Fix syntax in Kotlin example

    sbrannen committed Dec 19, 2020
    Copy the full SHA
    619a3ed View commit details

Commits on Jan 3, 2021

  1. Remove obsolete commandName attribute in spring-form.tld

    Since support for the commandName attribute was removed from the
    implementation of FormTag in Spring Framework 5.0, the presence of the
    commandName attribute in the spring-form.tld file is no longer valid
    and can lead one to assume that the commandName attribute is still
    supported -- for example when using code completion in a JSP editor.
    
    This commit therefore removes the obsolete commandName attribute in
    spring-form.tld.
    
    Closes gh-26337
    sbrannen committed Jan 3, 2021
    Copy the full SHA
    059cff5 View commit details

Commits on Jan 14, 2021

  1. Upgrade to RxJava 2.2.20, OpenPDF 1.3.24, Hibernate ORM 5.4.27, Joda-…

    …Time 2.10.9, Apache Johnzon 1.2.9
    jhoeller committed Jan 14, 2021
    Copy the full SHA
    3c030ed View commit details

Commits on Jan 19, 2021

  1. Copy the full SHA
    271a909 View commit details

Commits on Jan 27, 2021

  1. Copy the full SHA
    94ac2e4 View commit details
  2. Upgrade io.spring.ge.conventions plugin to version 0.0.7

    This will hopefully allow the build to pass again on the CI server.
    sbrannen committed Jan 27, 2021
    Copy the full SHA
    51079a4 View commit details

Commits on Jan 29, 2021

  1. Copy the full SHA
    698e74f View commit details
  2. Copy the full SHA
    6051f4e View commit details
  3. Copy the full SHA
    8a150ee View commit details

Commits on Feb 2, 2021

  1. Copy the full SHA
    7a9bf15 View commit details
  2. Copy the full SHA
    070c596 View commit details

Commits on Feb 3, 2021

  1. Polishing

    sbrannen committed Feb 3, 2021
    Copy the full SHA
    e18fba1 View commit details
  2. Do not retain partial column metadata in SimpleJdbcInsert

    Prior to this commit, if an SQLException was thrown while retrieving
    column metadata from the database, SimpleJdbcInsert would generate an
    INSERT statement that was syntactically valid but missing columns,
    which could lead to data silently missing in the database (for nullable
    columns).
    
    This commit fixes this by clearing all collected column metadata if an
    SQLException is thrown while processing the metadata. The result is
    that an InvalidDataAccessApiUsageException will be thrown later while
    generating the INSERT statement. The exception message now contains an
    additional hint to make use of SimpleJdbcInsert#usingColumns() in order
    to ensure that all required columns are included in the generated
    INSERT statement.
    
    SimpleJdbcCall can also encounter an SQLException while retrieving
    column metadata for a stored procedure/function, but an exception is
    not thrown since a later invocation of the stored procedure/function
    will likely fail anyway due to missing arguments. Consequently, this
    commit only improves the warning level log message by including a hint
    to make use of SimpleJdbcCall#addDeclaredParameter().
    
    Closes gh-26486
    sbrannen committed Feb 3, 2021
    Copy the full SHA
    236623f View commit details

Commits on Feb 4, 2021

  1. Fix StoredProcedure documentation in reference manual

    This commit aligns the documentation in the reference manual with the
    actual source code for StoredProcedure with regard to public execute()
    methods.
    
    Closes gh-26505
    sbrannen committed Feb 4, 2021
    Copy the full SHA
    6c22f7e View commit details

Commits on Feb 8, 2021

  1. Ensure StringDecoder supports multiline delimiters

    This commit makes sure the StringDecoder supports stripping off
    multi-line delimiters, such as \r\n. Specifically, we ensure that the
    delimiter is stripped from the joined buffer.
    
    Closes gh-26511
    poutsma committed Feb 8, 2021
    Copy the full SHA
    c09b251 View commit details

Commits on Feb 10, 2021

  1. Copy the full SHA
    594ec8f View commit details

Commits on Feb 14, 2021

  1. Fail early FactoryBean instantiation for LinkageError

    Closes gh-26425
    
    (cherry picked from commit defc246)
    jhoeller committed Feb 14, 2021
    Copy the full SHA
    27c5480 View commit details
  2. Consider non-initialized holders as equal to empty holders

    Closes gh-26433
    
    (cherry picked from commit d5e5dcb)
    jhoeller committed Feb 14, 2021
    Copy the full SHA
    64df931 View commit details
  3. Preserve resolved destroy method name in RootBeanDefinition

    Closes gh-26498
    
    (cherry picked from commit 809813d)
    jhoeller committed Feb 14, 2021
    Copy the full SHA
    a17c2cc View commit details
  4. Re-resolve cached arguments in case of NoSuchBeanDefinitionException

    Closes gh-26517
    
    (cherry picked from commit 99a1388)
    jhoeller committed Feb 14, 2021
    Copy the full SHA
    81be4c2 View commit details
  5. Copy the full SHA
    b4baa86 View commit details
  6. Polishing

    jhoeller committed Feb 14, 2021
    Copy the full SHA
    9f1e822 View commit details
  7. Copy the full SHA
    81f0d76 View commit details

Commits on Feb 15, 2021

  1. Copy the full SHA
    4ae3ab1 View commit details
  2. Copy the full SHA
    67979c9 View commit details
  3. Upgrade to Dysprosium-SR17

    Closes gh-26549
    rstoyanchev committed Feb 15, 2021
    Copy the full SHA
    29799be View commit details
  4. Copy the full SHA
    940f57d View commit details

Commits on Feb 16, 2021

  1. Copy the full SHA
    5d85e7f View commit details
Showing with 910 additions and 344 deletions.
  1. +9 −9 build.gradle
  2. +1 −1 gradle.properties
  3. +2 −2 settings.gradle
  4. +20 −13 spring-beans/src/main/java/org/springframework/beans/BeanUtils.java
  5. +3 −3 spring-beans/src/main/java/org/springframework/beans/TypeMismatchException.java
  6. +105 −81 .../main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java
  7. +6 −1 ...s/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java
  8. +23 −5 spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanDefinition.java
  9. +77 −76 spring-beans/src/main/java/org/springframework/beans/factory/support/DisposableBeanAdapter.java
  10. +6 −2 spring-beans/src/main/java/org/springframework/beans/factory/support/RootBeanDefinition.java
  11. +193 −1 .../java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessorTests.java
  12. +11 −1 spring-beans/src/test/java/org/springframework/beans/factory/support/BeanDefinitionTests.java
  13. +8 −4 spring-context/src/main/java/org/springframework/cache/annotation/CachePut.java
  14. +30 −6 ...ontext/src/main/java/org/springframework/validation/beanvalidation/LocalValidatorFactoryBean.java
  15. +3 −3 ...g-context/src/main/java/org/springframework/validation/beanvalidation/SpringValidatorAdapter.java
  16. +69 −1 ...src/test/java/org/springframework/context/annotation/AggressiveFactoryBeanInstantiationTests.java
  17. +7 −2 spring-context/src/test/java/org/springframework/context/annotation/EnableLoadTimeWeavingTests.java
  18. +1 −1 spring-core/src/main/java/org/springframework/asm/AnnotationVisitor.java
  19. +1 −1 spring-core/src/main/java/org/springframework/asm/ClassVisitor.java
  20. +1 −1 spring-core/src/main/java/org/springframework/asm/FieldVisitor.java
  21. +1 −1 spring-core/src/main/java/org/springframework/asm/MethodVisitor.java
  22. +1 −1 spring-core/src/main/java/org/springframework/asm/ModuleVisitor.java
  23. +1 −1 spring-core/src/main/java/org/springframework/asm/RecordComponentVisitor.java
  24. +1 −1 spring-core/src/main/java/org/springframework/asm/package-info.java
  25. +8 −4 spring-core/src/main/java/org/springframework/core/codec/StringDecoder.java
  26. +17 −2 spring-core/src/test/java/org/springframework/core/codec/StringDecoderTests.java
  27. +10 −2 spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/GenericCallMetaDataProvider.java
  28. +8 −3 spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/GenericTableMetaDataProvider.java
  29. +8 −3 spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/TableMetaDataContext.java
  30. +5 −4 spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/TableMetaDataProviderFactory.java
  31. +13 −6 spring-jdbc/src/main/java/org/springframework/jdbc/core/namedparam/NamedParameterUtils.java
  32. +3 −3 spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/AbstractJdbcCall.java
  33. +1 −1 spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/AbstractJdbcInsert.java
  34. +17 −1 spring-jdbc/src/test/java/org/springframework/jdbc/core/namedparam/NamedParameterUtilsTests.java
  35. +61 −28 spring-jdbc/src/test/java/org/springframework/jdbc/core/simple/SimpleJdbcCallTests.java
  36. +73 −16 spring-jdbc/src/test/java/org/springframework/jdbc/core/simple/SimpleJdbcInsertTests.java
  37. +6 −4 spring-test/src/main/java/org/springframework/mock/web/MockMultipartFile.java
  38. +6 −2 spring-web/src/main/java/org/springframework/http/server/reactive/NettyHeadersAdapter.java
  39. +11 −2 spring-web/src/main/java/org/springframework/web/server/adapter/HttpWebHandlerAdapter.java
  40. +8 −0 spring-web/src/test/java/org/springframework/http/server/reactive/HeadersAdaptersTests.java
  41. +22 −1 spring-web/src/test/java/org/springframework/web/util/UriComponentsBuilderTests.java
  42. +6 −4 spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockMultipartFile.java
  43. +6 −6 ...g-webflux/src/test/java/org/springframework/web/reactive/config/ResourceHandlerRegistryTests.java
  44. +2 −2 ...vc/src/main/java/org/springframework/web/servlet/mvc/support/DefaultHandlerExceptionResolver.java
  45. +0 −6 spring-webmvc/src/main/resources/META-INF/spring-form.tld
  46. +2 −2 spring-websocket/src/main/java/org/springframework/web/socket/WebSocketExtension.java
  47. +17 −3 spring-websocket/src/test/java/org/springframework/web/socket/WebSocketExtensionTests.java
  48. +6 −8 src/docs/asciidoc/data-access.adoc
  49. +1 −1 src/docs/asciidoc/index.adoc
  50. +6 −5 src/docs/asciidoc/testing.adoc
  51. +6 −6 src/docs/asciidoc/web/web-uris.adoc
  52. +1 −1 src/docs/dist/license.txt
18 changes: 9 additions & 9 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
plugins {
id 'io.spring.dependency-management' version '1.0.9.RELEASE' apply false
id 'io.spring.gradle-enterprise-conventions' version '0.0.2'
id 'io.spring.ge.conventions' version '0.0.7'
id 'io.spring.nohttp' version '0.0.5.RELEASE'
id 'org.jetbrains.kotlin.jvm' version '1.3.72' apply false
id 'org.jetbrains.dokka' version '0.10.1' apply false
@@ -29,7 +29,7 @@ configure(allprojects) { project ->
imports {
mavenBom "com.fasterxml.jackson:jackson-bom:2.10.5"
mavenBom "io.netty:netty-bom:4.1.51.Final"
mavenBom "io.projectreactor:reactor-bom:Dysprosium-SR15"
mavenBom "io.projectreactor:reactor-bom:Dysprosium-SR17"
mavenBom "io.rsocket:rsocket-bom:1.0.3"
mavenBom "org.eclipse.jetty:jetty-bom:9.4.31.v20200723"
mavenBom "org.jetbrains.kotlin:kotlin-bom:1.3.72"
@@ -61,7 +61,7 @@ configure(allprojects) { project ->

dependency "io.reactivex:rxjava:1.3.8"
dependency "io.reactivex:rxjava-reactive-streams:1.2.1"
dependency "io.reactivex.rxjava2:rxjava:2.2.19"
dependency "io.reactivex.rxjava2:rxjava:2.2.21"
dependency "io.projectreactor.tools:blockhound:1.0.4.RELEASE"

dependency "com.caucho:hessian:4.0.63"
@@ -76,7 +76,7 @@ configure(allprojects) { project ->
exclude group: "xpp3", name: "xpp3_min"
exclude group: "xmlpull", name: "xmlpull"
}
dependency "org.apache.johnzon:johnzon-jsonb:1.2.8"
dependency "org.apache.johnzon:johnzon-jsonb:1.2.10"
dependency("org.codehaus.jettison:jettison:1.3.8") {
exclude group: "stax", name: "stax-api"
}
@@ -88,8 +88,8 @@ configure(allprojects) { project ->
dependency "org.yaml:snakeyaml:1.27"

dependency "com.h2database:h2:1.4.200"
dependency "com.github.ben-manes.caffeine:caffeine:2.8.6"
dependency "com.github.librepdf:openpdf:1.3.23"
dependency "com.github.ben-manes.caffeine:caffeine:2.8.8"
dependency "com.github.librepdf:openpdf:1.3.25"
dependency "com.rometools:rome:1.12.2"
dependency "commons-io:commons-io:2.5"
dependency "io.vavr:vavr:0.10.3"
@@ -116,8 +116,8 @@ configure(allprojects) { project ->
dependency "net.sf.ehcache:ehcache:2.10.6"
dependency "org.ehcache:jcache:1.0.1"
dependency "org.ehcache:ehcache:3.4.0"
dependency "org.hibernate:hibernate-core:5.4.25.Final"
dependency "org.hibernate:hibernate-validator:6.1.6.Final"
dependency "org.hibernate:hibernate-core:5.4.28.Final"
dependency "org.hibernate:hibernate-validator:6.1.7.Final"
dependency "org.webjars:webjars-locator-core:0.46"
dependency "org.webjars:underscorejs:1.8.3"

@@ -225,7 +225,7 @@ configure(allprojects) { project ->

dependency "com.ibm.websphere:uow:6.0.2.17"
dependency "com.jamonapi:jamon:2.82"
dependency "joda-time:joda-time:2.10.6"
dependency "joda-time:joda-time:2.10.10"
dependency "org.eclipse.persistence:org.eclipse.persistence.jpa:2.7.7"
dependency "org.javamoney:moneta:1.3"

2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version=5.2.12.BUILD-SNAPSHOT
version=5.2.13.RELEASE
org.gradle.jvmargs=-Xmx1536M
org.gradle.caching=true
org.gradle.parallel=true
4 changes: 2 additions & 2 deletions settings.gradle
Original file line number Diff line number Diff line change
@@ -10,8 +10,8 @@ include "spring-aop"
include "spring-aspects"
include "spring-beans"
include "spring-context"
include "spring-context-support"
include "spring-context-indexer"
include "spring-context-support"
include "spring-core"
include "kotlin-coroutines"
project(':kotlin-coroutines').projectDir = file('spring-core/kotlin-coroutines')
@@ -26,8 +26,8 @@ include "spring-oxm"
include "spring-test"
include "spring-tx"
include "spring-web"
include "spring-webmvc"
include "spring-webflux"
include "spring-webmvc"
include "spring-websocket"
include "framework-bom"
include "integration-tests"
33 changes: 20 additions & 13 deletions spring-beans/src/main/java/org/springframework/beans/BeanUtils.java
Original file line number Diff line number Diff line change
@@ -506,6 +506,7 @@ public static PropertyEditor findEditorByConvention(@Nullable Class<?> targetTyp
if (targetType == null || targetType.isArray() || unknownEditorTypes.contains(targetType)) {
return null;
}

ClassLoader cl = targetType.getClassLoader();
if (cl == null) {
try {
@@ -522,28 +523,34 @@ public static PropertyEditor findEditorByConvention(@Nullable Class<?> targetTyp
return null;
}
}

String targetTypeName = targetType.getName();
String editorName = targetTypeName + "Editor";
try {
Class<?> editorClass = cl.loadClass(editorName);
if (!PropertyEditor.class.isAssignableFrom(editorClass)) {
if (logger.isInfoEnabled()) {
logger.info("Editor class [" + editorName +
"] does not implement [java.beans.PropertyEditor] interface");
if (editorClass != null) {
if (!PropertyEditor.class.isAssignableFrom(editorClass)) {
if (logger.isInfoEnabled()) {
logger.info("Editor class [" + editorName +
"] does not implement [java.beans.PropertyEditor] interface");
}
unknownEditorTypes.add(targetType);
return null;
}
unknownEditorTypes.add(targetType);
return null;
return (PropertyEditor) instantiateClass(editorClass);
}
return (PropertyEditor) instantiateClass(editorClass);
// Misbehaving ClassLoader returned null instead of ClassNotFoundException
// - fall back to unknown editor type registration below
}
catch (ClassNotFoundException ex) {
if (logger.isTraceEnabled()) {
logger.trace("No property editor [" + editorName + "] found for type " +
targetTypeName + " according to 'Editor' suffix convention");
}
unknownEditorTypes.add(targetType);
return null;
// Ignore - fall back to unknown editor type registration below
}
if (logger.isTraceEnabled()) {
logger.trace("No property editor [" + editorName + "] found for type " +
targetTypeName + " according to 'Editor' suffix convention");
}
unknownEditorTypes.add(targetType);
return null;
}

/**
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -41,10 +41,10 @@ public class TypeMismatchException extends PropertyAccessException {
private String propertyName;

@Nullable
private transient Object value;
private final transient Object value;

@Nullable
private Class<?> requiredType;
private final Class<?> requiredType;


/**
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -628,45 +628,58 @@ protected void inject(Object bean, @Nullable String beanName, @Nullable Property
Field field = (Field) this.member;
Object value;
if (this.cached) {
value = resolvedCachedArgument(beanName, this.cachedFieldValue);
}
else {
DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
desc.setContainingClass(bean.getClass());
Set<String> autowiredBeanNames = new LinkedHashSet<>(1);
Assert.state(beanFactory != null, "No BeanFactory available");
TypeConverter typeConverter = beanFactory.getTypeConverter();
try {
value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
value = resolvedCachedArgument(beanName, this.cachedFieldValue);
}
synchronized (this) {
if (!this.cached) {
Object cachedFieldValue = null;
if (value != null || this.required) {
cachedFieldValue = desc;
registerDependentBeans(beanName, autowiredBeanNames);
if (autowiredBeanNames.size() == 1) {
String autowiredBeanName = autowiredBeanNames.iterator().next();
if (beanFactory.containsBean(autowiredBeanName) &&
beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
cachedFieldValue = new ShortcutDependencyDescriptor(
desc, autowiredBeanName, field.getType());
}
}
}
this.cachedFieldValue = cachedFieldValue;
this.cached = true;
}
catch (NoSuchBeanDefinitionException ex) {
// Unexpected removal of target bean for cached argument -> re-resolve
value = resolveFieldValue(field, bean, beanName);
}
}
else {
value = resolveFieldValue(field, bean, beanName);
}
if (value != null) {
ReflectionUtils.makeAccessible(field);
field.set(bean, value);
}
}

@Nullable
private Object resolveFieldValue(Field field, Object bean, @Nullable String beanName) {
DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
desc.setContainingClass(bean.getClass());
Set<String> autowiredBeanNames = new LinkedHashSet<>(1);
Assert.state(beanFactory != null, "No BeanFactory available");
TypeConverter typeConverter = beanFactory.getTypeConverter();
Object value;
try {
value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
}
synchronized (this) {
if (!this.cached) {
Object cachedFieldValue = null;
if (value != null || this.required) {
cachedFieldValue = desc;
registerDependentBeans(beanName, autowiredBeanNames);
if (autowiredBeanNames.size() == 1) {
String autowiredBeanName = autowiredBeanNames.iterator().next();
if (beanFactory.containsBean(autowiredBeanName) &&
beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
cachedFieldValue = new ShortcutDependencyDescriptor(
desc, autowiredBeanName, field.getType());
}
}
}
this.cachedFieldValue = cachedFieldValue;
this.cached = true;
}
}
return value;
}
}


@@ -695,59 +708,17 @@ protected void inject(Object bean, @Nullable String beanName, @Nullable Property
Method method = (Method) this.member;
Object[] arguments;
if (this.cached) {
// Shortcut for avoiding synchronization...
arguments = resolveCachedArguments(beanName);
}
else {
int argumentCount = method.getParameterCount();
arguments = new Object[argumentCount];
DependencyDescriptor[] descriptors = new DependencyDescriptor[argumentCount];
Set<String> autowiredBeans = new LinkedHashSet<>(argumentCount);
Assert.state(beanFactory != null, "No BeanFactory available");
TypeConverter typeConverter = beanFactory.getTypeConverter();
for (int i = 0; i < arguments.length; i++) {
MethodParameter methodParam = new MethodParameter(method, i);
DependencyDescriptor currDesc = new DependencyDescriptor(methodParam, this.required);
currDesc.setContainingClass(bean.getClass());
descriptors[i] = currDesc;
try {
Object arg = beanFactory.resolveDependency(currDesc, beanName, autowiredBeans, typeConverter);
if (arg == null && !this.required) {
arguments = null;
break;
}
arguments[i] = arg;
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(methodParam), ex);
}
try {
arguments = resolveCachedArguments(beanName);
}
synchronized (this) {
if (!this.cached) {
if (arguments != null) {
DependencyDescriptor[] cachedMethodArguments = Arrays.copyOf(descriptors, arguments.length);
registerDependentBeans(beanName, autowiredBeans);
if (autowiredBeans.size() == argumentCount) {
Iterator<String> it = autowiredBeans.iterator();
Class<?>[] paramTypes = method.getParameterTypes();
for (int i = 0; i < paramTypes.length; i++) {
String autowiredBeanName = it.next();
if (beanFactory.containsBean(autowiredBeanName) &&
beanFactory.isTypeMatch(autowiredBeanName, paramTypes[i])) {
cachedMethodArguments[i] = new ShortcutDependencyDescriptor(
descriptors[i], autowiredBeanName, paramTypes[i]);
}
}
}
this.cachedMethodArguments = cachedMethodArguments;
}
else {
this.cachedMethodArguments = null;
}
this.cached = true;
}
catch (NoSuchBeanDefinitionException ex) {
// Unexpected removal of target bean for cached argument -> re-resolve
arguments = resolveMethodArguments(method, bean, beanName);
}
}
else {
arguments = resolveMethodArguments(method, bean, beanName);
}
if (arguments != null) {
try {
ReflectionUtils.makeAccessible(method);
@@ -771,6 +742,59 @@ private Object[] resolveCachedArguments(@Nullable String beanName) {
}
return arguments;
}

@Nullable
private Object[] resolveMethodArguments(Method method, Object bean, @Nullable String beanName) {
int argumentCount = method.getParameterCount();
Object[] arguments = new Object[argumentCount];
DependencyDescriptor[] descriptors = new DependencyDescriptor[argumentCount];
Set<String> autowiredBeans = new LinkedHashSet<>(argumentCount);
Assert.state(beanFactory != null, "No BeanFactory available");
TypeConverter typeConverter = beanFactory.getTypeConverter();
for (int i = 0; i < arguments.length; i++) {
MethodParameter methodParam = new MethodParameter(method, i);
DependencyDescriptor currDesc = new DependencyDescriptor(methodParam, this.required);
currDesc.setContainingClass(bean.getClass());
descriptors[i] = currDesc;
try {
Object arg = beanFactory.resolveDependency(currDesc, beanName, autowiredBeans, typeConverter);
if (arg == null && !this.required) {
arguments = null;
break;
}
arguments[i] = arg;
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(methodParam), ex);
}
}
synchronized (this) {
if (!this.cached) {
if (arguments != null) {
DependencyDescriptor[] cachedMethodArguments = Arrays.copyOf(descriptors, arguments.length);
registerDependentBeans(beanName, autowiredBeans);
if (autowiredBeans.size() == argumentCount) {
Iterator<String> it = autowiredBeans.iterator();
Class<?>[] paramTypes = method.getParameterTypes();
for (int i = 0; i < paramTypes.length; i++) {
String autowiredBeanName = it.next();
if (beanFactory.containsBean(autowiredBeanName) &&
beanFactory.isTypeMatch(autowiredBeanName, paramTypes[i])) {
cachedMethodArguments[i] = new ShortcutDependencyDescriptor(
descriptors[i], autowiredBeanName, paramTypes[i]);
}
}
}
this.cachedMethodArguments = cachedMethodArguments;
}
else {
this.cachedMethodArguments = null;
}
this.cached = true;
}
}
return arguments;
}
}


Loading