Skip to content

Commit adb64c7

Browse files
committed
Merge remote-tracking branch 'origin/main' into dev
2 parents 039c64b + 33a9295 commit adb64c7

File tree

143 files changed

+1922
-2558
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

143 files changed

+1922
-2558
lines changed

.github/workflows/update-antora-ui-spring.yml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@ permissions:
1212

1313
jobs:
1414
update-antora-ui-spring:
15-
runs-on: ubuntu-latest
1615
name: Update on Supported Branches
16+
if: ${{ github.repository == 'spring-projects/spring-framework' }}
17+
runs-on: ubuntu-latest
1718
strategy:
1819
matrix:
1920
branch: [ '6.1.x' ]
@@ -25,8 +26,9 @@ jobs:
2526
token: ${{ secrets.GITHUB_TOKEN }}
2627
antora-file-path: 'framework-docs/antora-playbook.yml'
2728
update-antora-ui-spring-docs-build:
28-
runs-on: ubuntu-latest
2929
name: Update on docs-build
30+
if: ${{ github.repository == 'spring-projects/spring-framework' }}
31+
runs-on: ubuntu-latest
3032
steps:
3133
- uses: spring-io/spring-doc-actions/update-antora-spring-ui@5a57bcc6a0da2a1474136cf29571b277850432bc
3234
name: Update

build.gradle

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,6 @@ configure([rootProject] + javaProjects) { project ->
8080
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
8181
testRuntimeOnly("org.junit.platform:junit-platform-suite-engine")
8282
testRuntimeOnly("org.apache.logging.log4j:log4j-core")
83-
testRuntimeOnly("org.apache.logging.log4j:log4j-jul")
84-
testRuntimeOnly("org.apache.logging.log4j:log4j-slf4j2-impl")
8583
// JSR-305 only used for non-required meta-annotations
8684
compileOnly("com.google.code.findbugs:jsr305")
8785
testCompileOnly("com.google.code.findbugs:jsr305")

buildSrc/src/main/java/org/springframework/build/CheckstyleConventions.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public void apply(Project project) {
5050
project.getPlugins().apply(CheckstylePlugin.class);
5151
project.getTasks().withType(Checkstyle.class).forEach(checkstyle -> checkstyle.getMaxHeapSize().set("1g"));
5252
CheckstyleExtension checkstyle = project.getExtensions().getByType(CheckstyleExtension.class);
53-
checkstyle.setToolVersion("10.20.1");
53+
checkstyle.setToolVersion("10.20.2");
5454
checkstyle.getConfigDirectory().set(project.getRootProject().file("src/checkstyle"));
5555
String version = SpringJavaFormatPlugin.class.getPackage().getImplementationVersion();
5656
DependencySet checkstyleDependencies = project.getConfigurations().getByName("checkstyle").getDependencies();

framework-docs/framework-docs.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,13 +69,13 @@ dependencies {
6969
api("jakarta.servlet:jakarta.servlet-api")
7070
api("jakarta.resource:jakarta.resource-api")
7171
api("jakarta.validation:jakarta.validation-api")
72+
api("jakarta.websocket:jakarta.websocket-client-api")
7273
api("javax.cache:cache-api")
7374
api("org.apache.activemq:activemq-ra:6.1.2")
7475
api("org.apache.commons:commons-dbcp2:2.11.0")
7576
api("org.aspectj:aspectjweaver")
7677
api("org.eclipse.jetty.websocket:jetty-websocket-jetty-api")
7778
api("org.jetbrains.kotlin:kotlin-stdlib")
78-
api("jakarta.websocket:jakarta.websocket-api")
7979

8080
implementation(project(":spring-core-test"))
8181
implementation("org.assertj:assertj-core")

framework-docs/modules/ROOT/nav.adoc

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,6 @@
101101
*** xref:core/aop-api/extensibility.adoc[]
102102
** xref:core/null-safety.adoc[]
103103
** xref:core/databuffer-codec.adoc[]
104-
** xref:core/spring-jcl.adoc[]
105104
** xref:core/aot.adoc[]
106105
** xref:core/appendix.adoc[]
107106
*** xref:core/appendix/xsd-schemas.adoc[]

framework-docs/modules/ROOT/pages/core/beans/context-introduction.adoc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -578,6 +578,8 @@ Kotlin::
578578
----
579579
======
580580

581+
NOTE: Do not define such beans to be lazy as the `ApplicationContext` will honour that and will not register the method to listen to events.
582+
581583
The method signature once again declares the event type to which it listens,
582584
but, this time, with a flexible name and without implementing a specific listener interface.
583585
The event type can also be narrowed through generics as long as the actual event type

framework-docs/modules/ROOT/pages/core/spring-jcl.adoc

Lines changed: 0 additions & 47 deletions
This file was deleted.

framework-docs/modules/ROOT/pages/testing/webtestclient.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ Kotlin::
127127
======
128128

129129
For Spring MVC, use the following where the Spring `ApplicationContext` is passed to
130-
{spring-framework-api}/test/web/servlet/setup/MockMvcBuilders.html#webAppContextSetup-org.springframework.web.context.WebApplicationContext-[MockMvcBuilders.webAppContextSetup]
130+
{spring-framework-api}/test/web/servlet/setup/MockMvcBuilders.html#webAppContextSetup(org.springframework.web.context.WebApplicationContext)[MockMvcBuilders.webAppContextSetup]
131131
to create a xref:testing/mockmvc.adoc[MockMvc] instance to handle
132132
requests:
133133

framework-docs/modules/ROOT/pages/web/websocket/server.adoc

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,10 +85,7 @@ for all HTTP processing -- including WebSocket handshake and all other HTTP
8585
requests -- such as Spring MVC's `DispatcherServlet`.
8686

8787
This is a significant limitation of JSR-356 that Spring's WebSocket support addresses with
88-
server-specific `RequestUpgradeStrategy` implementations even when running in a JSR-356 runtime.
89-
Such strategies currently exist for Tomcat, Jetty, GlassFish, WebLogic, WebSphere, and Undertow
90-
(and WildFly). As of Jakarta WebSocket 2.1, a standard request upgrade strategy is available
91-
which Spring chooses on Jakarta EE 10 based web containers such as Tomcat 10.1 and Jetty 12.
88+
a standard `RequestUpgradeStrategy` implementation when running in a WebSocket API 2.1+ runtime.
9289

9390
A secondary consideration is that Servlet containers with JSR-356 support are expected
9491
to perform a `ServletContainerInitializer` (SCI) scan that can slow down application

framework-platform/framework-platform.gradle

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,14 @@ javaPlatform {
77
}
88

99
dependencies {
10-
api(platform("com.fasterxml.jackson:jackson-bom:2.18.1"))
11-
api(platform("io.micrometer:micrometer-bom:1.14.0"))
10+
api(platform("com.fasterxml.jackson:jackson-bom:2.18.2"))
11+
api(platform("io.micrometer:micrometer-bom:1.14.2"))
1212
api(platform("io.netty:netty-bom:4.1.115.Final"))
1313
api(platform("io.netty:netty5-bom:5.0.0.Alpha5"))
14-
api(platform("io.projectreactor:reactor-bom:2024.0.0"))
14+
api(platform("io.projectreactor:reactor-bom:2024.0.1"))
1515
api(platform("io.rsocket:rsocket-bom:1.1.4"))
1616
api(platform("org.apache.groovy:groovy-bom:4.0.24"))
17-
api(platform("org.apache.logging.log4j:log4j-bom:2.21.1"))
17+
api(platform("org.apache.logging.log4j:log4j-bom:3.0.0-beta3"))
1818
api(platform("org.assertj:assertj-bom:3.26.3"))
1919
api(platform("org.eclipse.jetty:jetty-bom:12.0.15"))
2020
api(platform("org.eclipse.jetty.ee10:jetty-ee10-bom:12.0.15"))
@@ -45,6 +45,7 @@ dependencies {
4545
api("com.thoughtworks.qdox:qdox:2.1.0")
4646
api("com.thoughtworks.xstream:xstream:1.4.21")
4747
api("commons-io:commons-io:2.15.0")
48+
api("commons-logging:commons-logging:1.3.4")
4849
api("de.bechte.junit:junit-hierarchicalcontextrunner:4.12.2")
4950
api("io.micrometer:context-propagation:1.1.1")
5051
api("io.mockk:mockk:1.13.4")
@@ -53,7 +54,7 @@ dependencies {
5354
api("io.r2dbc:r2dbc-h2:1.0.0.RELEASE")
5455
api("io.r2dbc:r2dbc-spi-test:1.0.0.RELEASE")
5556
api("io.r2dbc:r2dbc-spi:1.0.0.RELEASE")
56-
api("io.reactivex.rxjava3:rxjava:3.1.9")
57+
api("io.reactivex.rxjava3:rxjava:3.1.10")
5758
api("io.smallrye.reactive:mutiny:1.10.0")
5859
api("io.undertow:undertow-core:2.3.18.Final")
5960
api("io.undertow:undertow-servlet:2.3.18.Final")
@@ -124,8 +125,8 @@ dependencies {
124125
api("org.glassfish:jakarta.el:4.0.2")
125126
api("org.graalvm.sdk:graal-sdk:22.3.1")
126127
api("org.hamcrest:hamcrest:2.2")
127-
api("org.hibernate:hibernate-core:7.0.0.Beta2")
128-
api("org.hibernate:hibernate-validator:9.0.0.Beta3")
128+
api("org.hibernate.orm:hibernate-core:7.0.0.Beta3")
129+
api("org.hibernate.validator:hibernate-validator:9.0.0.CR1")
129130
api("org.hsqldb:hsqldb:2.7.4")
130131
api("org.htmlunit:htmlunit:4.6.0")
131132
api("org.javamoney:moneta:1.4.4")
@@ -138,7 +139,6 @@ dependencies {
138139
api("org.seleniumhq.selenium:htmlunit3-driver:4.26.0")
139140
api("org.seleniumhq.selenium:selenium-java:4.26.0")
140141
api("org.skyscreamer:jsonassert:1.5.3")
141-
api("org.slf4j:slf4j-api:2.0.16")
142142
api("org.testng:testng:7.10.2")
143143
api("org.webjars:underscorejs:1.8.3")
144144
api("org.webjars:webjars-locator-lite:1.0.0")

integration-tests/integration-tests.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ dependencies {
2626
testImplementation("jakarta.servlet:jakarta.servlet-api")
2727
testImplementation("org.aspectj:aspectjweaver")
2828
testImplementation("org.hsqldb:hsqldb")
29-
testImplementation("org.hibernate:hibernate-core")
29+
testImplementation("org.hibernate.orm:hibernate-core")
3030
testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactor")
3131
}
3232

settings.gradle

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ include "spring-core"
1414
include "spring-core-test"
1515
include "spring-expression"
1616
include "spring-instrument"
17-
include "spring-jcl"
1817
include "spring-jdbc"
1918
include "spring-jms"
2019
include "spring-messaging"

spring-aop/src/main/java/org/springframework/aop/framework/ProxyFactoryBean.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2023 the original author or authors.
2+
* Copyright 2002-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -99,7 +99,7 @@ public class ProxyFactoryBean extends ProxyCreatorSupport
9999
public static final String GLOBAL_SUFFIX = "*";
100100

101101

102-
protected final Log logger = LogFactory.getLog(getClass());
102+
private static final Log logger = LogFactory.getLog(ProxyFactoryBean.class);
103103

104104
@Nullable
105105
private String[] interceptorNames;

spring-beans/src/main/java/org/springframework/beans/factory/aot/DefaultBeanRegistrationCodeFragments.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ public CodeBlock generateNewBeanDefinitionCode(GenerationContext generationConte
123123

124124
CodeBlock.Builder code = CodeBlock.builder();
125125
RootBeanDefinition mbd = this.registeredBean.getMergedBeanDefinition();
126-
Class<?> beanClass = (mbd.hasBeanClass() ? mbd.getBeanClass() : null);
126+
Class<?> beanClass = (mbd.hasBeanClass() ? ClassUtils.getUserClass(mbd.getBeanClass()) : null);
127127
CodeBlock beanClassCode = generateBeanClassCode(
128128
beanRegistrationCode.getClassName().packageName(),
129129
(beanClass != null ? beanClass : beanType.toClass()));

spring-beans/src/main/java/org/springframework/beans/factory/support/BeanDefinitionOverrideException.java

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2022 the original author or authors.
2+
* Copyright 2002-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -54,6 +54,22 @@ public BeanDefinitionOverrideException(
5454
this.existingDefinition = existingDefinition;
5555
}
5656

57+
/**
58+
* Create a new BeanDefinitionOverrideException for the given new and existing definition.
59+
* @param beanName the name of the bean
60+
* @param beanDefinition the newly registered bean definition
61+
* @param existingDefinition the existing bean definition for the same name
62+
* @param msg the detail message to include
63+
* @since 6.2.1
64+
*/
65+
public BeanDefinitionOverrideException(
66+
String beanName, BeanDefinition beanDefinition, BeanDefinition existingDefinition, String msg) {
67+
68+
super(beanDefinition.getResourceDescription(), beanName, msg);
69+
this.beanDefinition = beanDefinition;
70+
this.existingDefinition = existingDefinition;
71+
}
72+
5773

5874
/**
5975
* Return the description of the resource that the bean definition came from.

spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1170,6 +1170,11 @@ public void registerBeanDefinition(String beanName, BeanDefinition beanDefinitio
11701170
}
11711171
}
11721172
else {
1173+
if (logger.isInfoEnabled()) {
1174+
logger.info("Removing alias '" + beanName + "' for bean '" + aliasedName +
1175+
"' due to registration of bean definition for bean '" + beanName + "': [" +
1176+
beanDefinition + "]");
1177+
}
11731178
removeAlias(beanName);
11741179
}
11751180
}

spring-beans/src/test/java/org/springframework/beans/factory/DefaultListableBeanFactoryTests.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -870,10 +870,15 @@ void aliasChaining() {
870870
void beanDefinitionOverriding() {
871871
lbf.setAllowBeanDefinitionOverriding(true);
872872
lbf.registerBeanDefinition("test", new RootBeanDefinition(TestBean.class));
873+
// Override "test" bean definition.
873874
lbf.registerBeanDefinition("test", new RootBeanDefinition(NestedTestBean.class));
875+
// Temporary "test2" alias for nonexistent bean.
874876
lbf.registerAlias("otherTest", "test2");
877+
// Reassign "test2" alias to "test".
875878
lbf.registerAlias("test", "test2");
879+
// Assign "testX" alias to "test" as well.
876880
lbf.registerAlias("test", "testX");
881+
// Register new "testX" bean definition which also removes the "testX" alias for "test".
877882
lbf.registerBeanDefinition("testX", new RootBeanDefinition(TestBean.class));
878883

879884
assertThat(lbf.getBean("test")).isInstanceOf(NestedTestBean.class);

spring-context/spring-context.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ dependencies {
2626
optional("org.apache-extras.beanshell:bsh")
2727
optional("org.aspectj:aspectjweaver")
2828
optional("org.crac:crac")
29-
optional("org.hibernate:hibernate-validator")
29+
optional("org.hibernate.validator:hibernate-validator")
3030
optional("org.jetbrains.kotlin:kotlin-reflect")
3131
optional("org.jetbrains.kotlin:kotlin-stdlib")
3232
optional("org.jetbrains.kotlinx:kotlinx-coroutines-core")

spring-context/src/main/java/org/springframework/context/annotation/Configuration.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2023 the original author or authors.
2+
* Copyright 2002-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -471,7 +471,10 @@
471471
* Switch this flag to {@code false} in order to allow for method overloading
472472
* according to those semantics, accepting the risk for accidental overlaps.
473473
* @since 6.0
474+
* @deprecated as of 7.0, always relying on {@code @Bean} unique methods,
475+
* just possibly with {@code Optional}/{@code ObjectProvider} arguments
474476
*/
477+
@Deprecated(since = "7.0")
475478
boolean enforceUniqueMethods() default true;
476479

477480
}

spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassBeanDefinitionReader.java

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,10 @@
3636
import org.springframework.beans.factory.parsing.SourceExtractor;
3737
import org.springframework.beans.factory.support.AbstractBeanDefinition;
3838
import org.springframework.beans.factory.support.AbstractBeanDefinitionReader;
39+
import org.springframework.beans.factory.support.BeanDefinitionOverrideException;
3940
import org.springframework.beans.factory.support.BeanDefinitionReader;
4041
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
4142
import org.springframework.beans.factory.support.BeanNameGenerator;
42-
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
4343
import org.springframework.beans.factory.support.RootBeanDefinition;
4444
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
4545
import org.springframework.context.annotation.ConfigurationCondition.ConfigurationPhase;
@@ -292,23 +292,34 @@ private void loadBeanDefinitionsForBeanMethod(BeanMethod beanMethod) {
292292
this.registry.registerBeanDefinition(beanName, beanDefToRegister);
293293
}
294294

295+
@SuppressWarnings("NullAway")
295296
protected boolean isOverriddenByExistingDefinition(BeanMethod beanMethod, String beanName) {
296297
if (!this.registry.containsBeanDefinition(beanName)) {
297298
return false;
298299
}
299300
BeanDefinition existingBeanDef = this.registry.getBeanDefinition(beanName);
301+
ConfigurationClass configClass = beanMethod.getConfigurationClass();
300302

301303
// If the bean method is an overloaded case on the same configuration class,
302304
// preserve the existing bean definition and mark it as overloaded.
303305
if (existingBeanDef instanceof ConfigurationClassBeanDefinition ccbd) {
304-
if (ccbd.getMetadata().getClassName().equals(beanMethod.getConfigurationClass().getMetadata().getClassName()) &&
305-
ccbd.getFactoryMethodMetadata().getMethodName().equals(beanMethod.getMetadata().getMethodName())) {
306+
if (!ccbd.getMetadata().getClassName().equals(configClass.getMetadata().getClassName())) {
307+
return false;
308+
}
309+
if (ccbd.getFactoryMethodMetadata().getMethodName().equals(beanMethod.getMetadata().getMethodName())) {
306310
ccbd.setNonUniqueFactoryMethodName(ccbd.getFactoryMethodMetadata().getMethodName());
307311
return true;
308312
}
309-
else {
310-
return false;
313+
Map<String, Object> attributes =
314+
configClass.getMetadata().getAnnotationAttributes(Configuration.class.getName());
315+
if ((attributes != null && (Boolean) attributes.get("enforceUniqueMethods")) ||
316+
!this.registry.isBeanDefinitionOverridable(beanName)) {
317+
throw new BeanDefinitionOverrideException(beanName,
318+
new ConfigurationClassBeanDefinition(configClass, beanMethod.getMetadata(), beanName),
319+
existingBeanDef,
320+
"@Bean method override with same bean name but different method name: " + existingBeanDef);
311321
}
322+
return true;
312323
}
313324

314325
// A bean definition resulting from a component scan can be silently overridden
@@ -329,9 +340,11 @@ protected boolean isOverriddenByExistingDefinition(BeanMethod beanMethod, String
329340

330341
// At this point, it's a top-level override (probably XML), just having been parsed
331342
// before configuration class processing kicks in...
332-
if (this.registry instanceof DefaultListableBeanFactory dlbf && !dlbf.isBeanDefinitionOverridable(beanName)) {
333-
throw new BeanDefinitionStoreException(beanMethod.getConfigurationClass().getResource().getDescription(),
334-
beanName, "@Bean definition illegally overridden by existing bean definition: " + existingBeanDef);
343+
if (!this.registry.isBeanDefinitionOverridable(beanName)) {
344+
throw new BeanDefinitionOverrideException(beanName,
345+
new ConfigurationClassBeanDefinition(configClass, beanMethod.getMetadata(), beanName),
346+
existingBeanDef,
347+
"@Bean definition illegally overridden by existing bean definition: " + existingBeanDef);
335348
}
336349
if (logger.isDebugEnabled()) {
337350
logger.debug(String.format("Skipping bean definition for %s: a definition for bean '%s' " +

0 commit comments

Comments
 (0)