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.10.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.11.RELEASE
Choose a head ref
  • 18 commits
  • 42 files changed
  • 6 contributors

Commits on Oct 27, 2020

  1. Copy the full SHA
    a9dec6a View commit details

Commits on Oct 29, 2020

  1. Copy default headers, cookies in WebClient builder

    This commit makes copies of the default headers and cookies when a
    WebClient is built, so that subsequent changes to these do not affect
    previously built clients.
    
    Closes: gh-25992
    poutsma committed Oct 29, 2020
    Copy the full SHA
    0acb1e5 View commit details

Commits on Oct 30, 2020

  1. Copy the full SHA
    af1d721 View commit details
  2. Copy the full SHA
    01827fd View commit details
  3. Remove unused import

    rstoyanchev committed Oct 30, 2020
    Copy the full SHA
    8c3cdc6 View commit details

Commits on Nov 2, 2020

  1. Copy the full SHA
    b4f8fc8 View commit details
  2. Preserve registration order in @activeprofiles

    With this commit, bean definition profiles declared via @activeprofiles
    are once again stored in registration order, in order to support use
    cases in Spring Boot and other frameworks that depend on the
    registration order.
    
    This effectively reverts the changes made in conjunction with gh-25973.
    
    Closes gh-26004
    sbrannen committed Nov 2, 2020
    Copy the full SHA
    e713e0d View commit details

Commits on Nov 5, 2020

  1. Reliably refresh metadata for dynamically changing prototype bean class

    Closes gh-26019
    
    (cherry picked from commit 412aa06)
    jhoeller committed Nov 5, 2020
    Copy the full SHA
    10bff05 View commit details
  2. Upgrade to Hibernate ORM 5.4.23

    (cherry picked from commit b815acc)
    jhoeller committed Nov 5, 2020
    Copy the full SHA
    09c1e98 View commit details
  3. Copy the full SHA
    dbbedc6 View commit details
  4. Copy the full SHA
    58aa065 View commit details
  5. Polishing

    jhoeller committed Nov 5, 2020
    Copy the full SHA
    7881329 View commit details
  6. Copy the full SHA
    5b06c23 View commit details
  7. Refine logging in StompErrorHandler

    Avoid a full stacktrace at ERROR level for a client message that could
    not be sent to a MessageChannel.
    
    See gh-26026
    rstoyanchev committed Nov 5, 2020
    Copy the full SHA
    010d094 View commit details

Commits on Nov 8, 2020

  1. Do not create intermediate list in MergedAnnotationCollectors.toAnnot…

    …ationSet()
    
    Prior to this commit, MergedAnnotationCollectors.toAnnotationSet()
    created an intermediate ArrayList for storing the results prior to
    creating a LinkedHashSet in the finishing step.
    
    Since the creation of the intermediate list is unnecessary, this commit
    simplifies the implementation of toAnnotationSet() by using the
    Collector.of() factory method that does not accept a `finisher` argument.
    The resulting Collector internally uses a `castingIdentity()` function
    as the `finisher`.
    
    Closes gh-26031
    sbrannen committed Nov 8, 2020
    Copy the full SHA
    da4e37d View commit details

Commits on Nov 9, 2020

  1. Polishing

    jhoeller committed Nov 9, 2020
    Copy the full SHA
    cde95e1 View commit details
  2. Polishing

    jhoeller committed Nov 9, 2020
    Copy the full SHA
    e9416b3 View commit details

Commits on Nov 10, 2020

  1. Copy the full SHA
    41fd015 View commit details
Showing with 442 additions and 279 deletions.
  1. +1 −1 build.gradle
  2. +1 −1 gradle.properties
  3. +6 −4 spring-aop/src/main/java/org/springframework/aop/aspectj/MethodInvocationProceedingJoinPoint.java
  4. +6 −4 spring-beans/src/main/java/org/springframework/beans/AbstractNestablePropertyAccessor.java
  5. +33 −20 spring-beans/src/main/java/org/springframework/beans/AbstractPropertyAccessor.java
  6. +2 −3 spring-beans/src/main/java/org/springframework/beans/DirectFieldAccessor.java
  7. +7 −8 .../main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java
  8. +2 −12 spring-beans/src/main/java/org/springframework/beans/factory/annotation/InjectionMetadata.java
  9. +9 −0 ...c/main/java/org/springframework/context/annotation/FullyQualifiedAnnotationBeanNameGenerator.java
  10. +55 −0 .../java/org/springframework/context/annotation/configuration/ConfigurationClassProcessingTests.java
  11. +30 −17 spring-core/src/main/java/org/springframework/core/annotation/MergedAnnotationCollectors.java
  12. +23 −15 spring-expression/src/main/java/org/springframework/expression/spel/standard/SpelCompiler.java
  13. +0 −1 spring-expression/src/test/java/org/springframework/expression/spel/SpelReproTests.java
  14. +4 −2 spring-expression/src/test/java/org/springframework/expression/spel/testresources/Person.java
  15. +22 −16 spring-expression/src/test/java/org/springframework/expression/spel/testresources/TestAddress.java
  16. +22 −16 spring-expression/src/test/java/org/springframework/expression/spel/testresources/TestPerson.java
  17. +11 −9 spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/CallMetaDataContext.java
  18. +1 −2 ...ssaging/src/main/java/org/springframework/messaging/simp/config/StompBrokerRelayRegistration.java
  19. +2 −2 spring-test/src/main/java/org/springframework/test/context/ActiveProfiles.java
  20. +4 −4 spring-test/src/main/java/org/springframework/test/context/MergedContextConfiguration.java
  21. +18 −7 spring-test/src/main/java/org/springframework/test/context/support/ActiveProfilesUtils.java
  22. +7 −21 ...ng-test/src/main/java/org/springframework/test/context/support/DefaultActiveProfilesResolver.java
  23. +3 −3 spring-test/src/test/java/org/springframework/test/context/MergedContextConfigurationTests.java
  24. +3 −3 spring-test/src/test/java/org/springframework/test/context/cache/ContextCacheTests.java
  25. +7 −7 spring-test/src/test/java/org/springframework/test/context/support/ActiveProfilesUtilsTests.java
  26. +4 −1 ...b/src/main/java/org/springframework/http/converter/json/AbstractJackson2HttpMessageConverter.java
  27. +5 −5 spring-web/src/main/java/org/springframework/web/method/annotation/MapMethodProcessor.java
  28. +3 −3 spring-web/src/main/java/org/springframework/web/method/annotation/ModelMethodProcessor.java
  29. +4 −1 ...c/test/java/org/springframework/http/converter/json/MappingJackson2HttpMessageConverterTests.java
  30. +9 −9 spring-web/src/test/java/org/springframework/web/util/UriComponentsBuilderTests.java
  31. +41 −40 spring-web/src/test/java/org/springframework/web/util/UriComponentsTests.java
  32. +11 −15 spring-web/src/test/java/org/springframework/web/util/UriTemplateTests.java
  33. +31 −2 ...bflux/src/main/java/org/springframework/web/reactive/function/client/DefaultWebClientBuilder.java
  34. +1 −3 spring-webflux/src/main/java/org/springframework/web/reactive/socket/WebSocketSession.java
  35. +31 −1 ...webflux/src/test/java/org/springframework/web/reactive/function/client/DefaultWebClientTests.java
  36. +2 −2 ...vc/src/main/java/org/springframework/web/servlet/config/AnnotationDrivenBeanDefinitionParser.java
  37. +3 −3 ...ng-webmvc/src/main/java/org/springframework/web/servlet/config/ResourcesBeanDefinitionParser.java
  38. +3 −2 spring-webmvc/src/test/java/org/springframework/web/servlet/DispatcherServletTests.java
  39. +1 −2 spring-websocket/src/main/java/org/springframework/web/socket/WebSocketSession.java
  40. +6 −9 spring-websocket/src/main/java/org/springframework/web/socket/messaging/DefaultSimpUserRegistry.java
  41. +7 −2 spring-websocket/src/main/java/org/springframework/web/socket/messaging/StompSubProtocolHandler.java
  42. +1 −1 src/docs/asciidoc/core/core-resources.adoc
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
@@ -116,7 +116,7 @@ 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.22.Final"
dependency "org.hibernate:hibernate-core:5.4.23.Final"
dependency "org.hibernate:hibernate-validator:6.1.6.Final"
dependency "org.webjars:webjars-locator-core:0.46"
dependency "org.webjars:underscorejs:1.8.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.10.BUILD-SNAPSHOT
version=5.2.11.RELEASE
org.gradle.jvmargs=-Xmx1536M
org.gradle.caching=true
org.gradle.parallel=true
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2020 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.
@@ -219,10 +219,12 @@ public Class<?>[] getParameterTypes() {
@Override
@Nullable
public String[] getParameterNames() {
if (this.parameterNames == null) {
this.parameterNames = parameterNameDiscoverer.getParameterNames(getMethod());
String[] parameterNames = this.parameterNames;
if (parameterNames == null) {
parameterNames = parameterNameDiscoverer.getParameterNames(getMethod());
this.parameterNames = parameterNames;
}
return this.parameterNames;
return parameterNames;
}

@Override
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2020 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.
@@ -422,9 +422,12 @@ private void processLocalProperty(PropertyTokenHolder tokens, PropertyValue pv)
}
return;
}
else {
throw createNotWritablePropertyException(tokens.canonicalName);
if (this.suppressNotWritablePropertyException) {
// Optimization for common ignoreUnknown=true scenario since the
// exception would be caught and swallowed higher up anyway...
return;
}
throw createNotWritablePropertyException(tokens.canonicalName);
}

Object oldValue = null;
@@ -806,7 +809,6 @@ protected String getFinalPath(AbstractNestablePropertyAccessor pa, String nested
* @param propertyPath property path, which may be nested
* @return a property accessor for the target bean
*/
@SuppressWarnings("unchecked") // avoid nested generic
protected AbstractNestablePropertyAccessor getPropertyAccessorForPropertyPath(String propertyPath) {
int pos = PropertyAccessorUtils.getFirstNestedPropertySeparatorIndex(propertyPath);
// Handle nested properties recursively.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2020 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.
@@ -40,6 +40,8 @@ public abstract class AbstractPropertyAccessor extends TypeConverterSupport impl

private boolean autoGrowNestedPaths = false;

boolean suppressNotWritablePropertyException = false;


@Override
public void setExtractOldValueForEditor(boolean extractOldValueForEditor) {
@@ -89,30 +91,41 @@ public void setPropertyValues(PropertyValues pvs, boolean ignoreUnknown, boolean
List<PropertyAccessException> propertyAccessExceptions = null;
List<PropertyValue> propertyValues = (pvs instanceof MutablePropertyValues ?
((MutablePropertyValues) pvs).getPropertyValueList() : Arrays.asList(pvs.getPropertyValues()));
for (PropertyValue pv : propertyValues) {
try {
// This method may throw any BeansException, which won't be caught

if (ignoreUnknown) {
this.suppressNotWritablePropertyException = true;
}
try {
for (PropertyValue pv : propertyValues) {
// setPropertyValue may throw any BeansException, which won't be caught
// here, if there is a critical failure such as no matching field.
// We can attempt to deal only with less serious exceptions.
setPropertyValue(pv);
}
catch (NotWritablePropertyException ex) {
if (!ignoreUnknown) {
throw ex;
try {
setPropertyValue(pv);
}
// Otherwise, just ignore it and continue...
}
catch (NullValueInNestedPathException ex) {
if (!ignoreInvalid) {
throw ex;
catch (NotWritablePropertyException ex) {
if (!ignoreUnknown) {
throw ex;
}
// Otherwise, just ignore it and continue...
}
// Otherwise, just ignore it and continue...
}
catch (PropertyAccessException ex) {
if (propertyAccessExceptions == null) {
propertyAccessExceptions = new ArrayList<>();
catch (NullValueInNestedPathException ex) {
if (!ignoreInvalid) {
throw ex;
}
// Otherwise, just ignore it and continue...
}
catch (PropertyAccessException ex) {
if (propertyAccessExceptions == null) {
propertyAccessExceptions = new ArrayList<>();
}
propertyAccessExceptions.add(ex);
}
propertyAccessExceptions.add(ex);
}
}
finally {
if (ignoreUnknown) {
this.suppressNotWritablePropertyException = false;
}
}

Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2020 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.
@@ -92,8 +92,7 @@ protected DirectFieldAccessor newNestedPropertyAccessor(Object object, String ne
@Override
protected NotWritablePropertyException createNotWritablePropertyException(String propertyName) {
PropertyMatches matches = PropertyMatches.forField(propertyName, getRootClass());
throw new NotWritablePropertyException(
getRootClass(), getNestedPath() + propertyName,
throw new NotWritablePropertyException(getRootClass(), getNestedPath() + propertyName,
matches.buildErrorMessage(), matches.getPossibleMatches());
}

Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2020 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.
@@ -613,7 +613,7 @@ private class AutowiredFieldElement extends InjectionMetadata.InjectedElement {

private final boolean required;

private volatile boolean cached = false;
private volatile boolean cached;

@Nullable
private volatile Object cachedFieldValue;
@@ -644,21 +644,20 @@ protected void inject(Object bean, @Nullable String beanName, @Nullable Property
}
synchronized (this) {
if (!this.cached) {
Object cachedFieldValue = null;
if (value != null || this.required) {
this.cachedFieldValue = desc;
cachedFieldValue = desc;
registerDependentBeans(beanName, autowiredBeanNames);
if (autowiredBeanNames.size() == 1) {
String autowiredBeanName = autowiredBeanNames.iterator().next();
if (beanFactory.containsBean(autowiredBeanName) &&
beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
this.cachedFieldValue = new ShortcutDependencyDescriptor(
cachedFieldValue = new ShortcutDependencyDescriptor(
desc, autowiredBeanName, field.getType());
}
}
}
else {
this.cachedFieldValue = null;
}
this.cachedFieldValue = cachedFieldValue;
this.cached = true;
}
}
@@ -678,7 +677,7 @@ private class AutowiredMethodElement extends InjectionMetadata.InjectedElement {

private final boolean required;

private volatile boolean cached = false;
private volatile boolean cached;

@Nullable
private volatile Object[] cachedMethodArguments;
Original file line number Diff line number Diff line change
@@ -26,9 +26,6 @@
import java.util.LinkedHashSet;
import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.support.RootBeanDefinition;
@@ -69,8 +66,6 @@ public void clear(@Nullable PropertyValues pvs) {
};


private static final Log logger = LogFactory.getLog(InjectionMetadata.class);

private final Class<?> targetClass;

private final Collection<InjectedElement> injectedElements;
@@ -110,9 +105,6 @@ public void checkConfigMembers(RootBeanDefinition beanDefinition) {
if (!beanDefinition.isExternallyManagedConfigMember(member)) {
beanDefinition.registerExternallyManagedConfigMember(member);
checkedElements.add(element);
if (logger.isTraceEnabled()) {
logger.trace("Registered injected element on class [" + this.targetClass.getName() + "]: " + element);
}
}
}
this.checkedElements = checkedElements;
@@ -124,9 +116,6 @@ public void inject(Object target, @Nullable String beanName, @Nullable PropertyV
(checkedElements != null ? checkedElements : this.injectedElements);
if (!elementsToIterate.isEmpty()) {
for (InjectedElement element : elementsToIterate) {
if (logger.isTraceEnabled()) {
logger.trace("Processing injected element of bean '" + beanName + "': " + element);
}
element.inject(target, beanName, pvs);
}
}
@@ -157,7 +146,8 @@ public void clear(@Nullable PropertyValues pvs) {
* @since 5.2
*/
public static InjectionMetadata forElements(Collection<InjectedElement> elements, Class<?> clazz) {
return (elements.isEmpty() ? InjectionMetadata.EMPTY : new InjectionMetadata(clazz, elements));
return (elements.isEmpty() ? new InjectionMetadata(clazz, Collections.emptyList()) :
new InjectionMetadata(clazz, elements));
}

/**
Original file line number Diff line number Diff line change
@@ -43,6 +43,15 @@
*/
public class FullyQualifiedAnnotationBeanNameGenerator extends AnnotationBeanNameGenerator {

/**
* A convenient constant for a default {@code FullyQualifiedAnnotationBeanNameGenerator}
* instance, as used for configuration-level import purposes.
* @since 5.2.11
*/
public static final FullyQualifiedAnnotationBeanNameGenerator INSTANCE =
new FullyQualifiedAnnotationBeanNameGenerator();


@Override
protected String buildDefaultBeanName(BeanDefinition definition) {
String beanClassName = definition.getBeanClassName();
Original file line number Diff line number Diff line change
@@ -307,6 +307,23 @@ public void configurationWithOverloadedBeanMismatchWithAsm() {
assertThat(tb.getLawyer()).isEqualTo(ctx.getBean(NestedTestBean.class));
}

@Test // gh-26019
public void autowiringWithDynamicPrototypeBeanClass() {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(
ConfigWithDynamicPrototype.class, PrototypeDependency.class);

PrototypeInterface p1 = ctx.getBean(PrototypeInterface.class, 1);
assertThat(p1).isInstanceOf(PrototypeOne.class);
assertThat(((PrototypeOne) p1).prototypeDependency).isNotNull();

PrototypeInterface p2 = ctx.getBean(PrototypeInterface.class, 2);
assertThat(p2).isInstanceOf(PrototypeTwo.class);

PrototypeInterface p3 = ctx.getBean(PrototypeInterface.class, 1);
assertThat(p3).isInstanceOf(PrototypeOne.class);
assertThat(((PrototypeOne) p3).prototypeDependency).isNotNull();
}


/**
* Creates a new {@link BeanFactory}, populates it with a {@link BeanDefinition}
@@ -632,4 +649,42 @@ public TestBean foo(@Qualifier("other") NestedTestBean other) {
}
}


static class PrototypeDependency {
}

interface PrototypeInterface {
}

static class PrototypeOne extends AbstractPrototype {

@Autowired
PrototypeDependency prototypeDependency;

}

static class PrototypeTwo extends AbstractPrototype {

// no autowired dependency here, in contrast to above
}

static class AbstractPrototype implements PrototypeInterface {
}

@Configuration
static class ConfigWithDynamicPrototype {

@Bean
@Scope(value = "prototype")
public PrototypeInterface getDemoBean( int i) {
switch ( i) {
case 1: return new PrototypeOne();
case 2:
default:
return new PrototypeTwo();

}
}
}

}
Loading