Skip to content

Commit b9c1aec

Browse files
committed
Merge branch '6.2.x'
2 parents c022516 + 3c3b8c7 commit b9c1aec

11 files changed

+129
-77
lines changed

spring-test/src/main/java/org/springframework/test/context/bean/override/BeanOverrideHandler.java

+24-8
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
import java.lang.annotation.Annotation;
2020
import java.lang.reflect.Field;
2121
import java.lang.reflect.Modifier;
22-
import java.util.Arrays;
2322
import java.util.Collections;
2423
import java.util.HashSet;
2524
import java.util.LinkedList;
@@ -73,7 +72,7 @@ public abstract class BeanOverrideHandler {
7372

7473
private final Field field;
7574

76-
private final Set<Annotation> fieldAnnotations;
75+
private final Set<Annotation> qualifierAnnotations;
7776

7877
private final ResolvableType beanType;
7978

@@ -86,7 +85,7 @@ protected BeanOverrideHandler(Field field, ResolvableType beanType, @Nullable St
8685
BeanOverrideStrategy strategy) {
8786

8887
this.field = field;
89-
this.fieldAnnotations = annotationSet(field);
88+
this.qualifierAnnotations = getQualifierAnnotations(field);
9089
this.beanType = beanType;
9190
this.beanName = beanName;
9291
this.strategy = strategy;
@@ -242,20 +241,22 @@ public boolean equals(Object other) {
242241
!Objects.equals(this.strategy, that.strategy)) {
243242
return false;
244243
}
244+
245+
// by-name lookup
245246
if (this.beanName != null) {
246247
return true;
247248
}
248249

249250
// by-type lookup
250251
return (Objects.equals(this.field.getName(), that.field.getName()) &&
251-
this.fieldAnnotations.equals(that.fieldAnnotations));
252+
this.qualifierAnnotations.equals(that.qualifierAnnotations));
252253
}
253254

254255
@Override
255256
public int hashCode() {
256257
int hash = Objects.hash(getClass(), this.beanType.getType(), this.beanName, this.strategy);
257258
return (this.beanName != null ? hash : hash +
258-
Objects.hash(this.field.getName(), this.fieldAnnotations));
259+
Objects.hash(this.field.getName(), this.qualifierAnnotations));
259260
}
260261

261262
@Override
@@ -268,9 +269,24 @@ public String toString() {
268269
.toString();
269270
}
270271

271-
private static Set<Annotation> annotationSet(Field field) {
272-
Annotation[] annotations = field.getAnnotations();
273-
return (annotations.length != 0 ? new HashSet<>(Arrays.asList(annotations)) : Collections.emptySet());
272+
273+
private static Set<Annotation> getQualifierAnnotations(Field field) {
274+
Annotation[] candidates = field.getDeclaredAnnotations();
275+
if (candidates.length == 0) {
276+
return Collections.emptySet();
277+
}
278+
Set<Annotation> annotations = new HashSet<>(candidates.length - 1);
279+
for (Annotation candidate : candidates) {
280+
// Assume all non-BeanOverride annotations are "qualifiers".
281+
if (!isBeanOverrideAnnotation(candidate.annotationType())) {
282+
annotations.add(candidate);
283+
}
284+
}
285+
return annotations;
286+
}
287+
288+
private static boolean isBeanOverrideAnnotation(Class<? extends Annotation> type) {
289+
return MergedAnnotations.from(type).isPresent(BeanOverride.class);
274290
}
275291

276292
}

spring-test/src/main/java/org/springframework/test/context/bean/override/BeanOverrideProcessor.java

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2024 the original author or authors.
2+
* Copyright 2002-2025 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.
@@ -36,7 +36,6 @@
3636
* @author Sam Brannen
3737
* @since 6.2
3838
*/
39-
@FunctionalInterface
4039
public interface BeanOverrideProcessor {
4140

4241
/**

spring-test/src/main/java/org/springframework/test/context/bean/override/BeanOverrideRegistry.java

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2024 the original author or authors.
2+
* Copyright 2002-2025 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.
@@ -109,8 +109,7 @@ Object wrapBeanIfNecessary(Object bean, String beanName) {
109109

110110
void inject(Object target, BeanOverrideHandler handler) {
111111
String beanName = this.handlerToBeanNameMap.get(handler);
112-
Assert.state(StringUtils.hasLength(beanName),
113-
() -> "No bean found for BeanOverrideHandler: " + handler);
112+
Assert.state(StringUtils.hasLength(beanName), () -> "No bean found for BeanOverrideHandler: " + handler);
114113
inject(handler.getField(), target, beanName);
115114
}
116115

spring-test/src/main/java/org/springframework/test/context/bean/override/mockito/MockBeans.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2024 the original author or authors.
2+
* Copyright 2002-2025 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.

spring-test/src/test/java/org/springframework/test/context/bean/override/BeanOverrideBeanFactoryPostProcessorTests.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2024 the original author or authors.
2+
* Copyright 2002-2025 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.
@@ -395,7 +395,7 @@ private void qualifiedElementIsField(RootBeanDefinition def) {
395395

396396
private static AnnotationConfigApplicationContext createContext(Class<?> testClass) {
397397
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
398-
Set<BeanOverrideHandler> handlers = new LinkedHashSet<>(BeanOverrideHandler.forTestClass(testClass));
398+
Set<BeanOverrideHandler> handlers = new LinkedHashSet<>(BeanOverrideTestUtils.findHandlers(testClass));
399399
new BeanOverrideContextCustomizer(handlers).customizeContext(context, mock(MergedContextConfiguration.class));
400400
return context;
401401
}

spring-test/src/test/java/org/springframework/test/context/bean/override/BeanOverrideHandlerTests.java

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2024 the original author or authors.
2+
* Copyright 2002-2025 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.
@@ -51,14 +51,14 @@ class BeanOverrideHandlerTests {
5151

5252
@Test
5353
void forTestClassWithSingleField() {
54-
List<BeanOverrideHandler> handlers = BeanOverrideHandler.forTestClass(SingleAnnotation.class);
54+
List<BeanOverrideHandler> handlers = BeanOverrideTestUtils.findHandlers(SingleAnnotation.class);
5555
assertThat(handlers).singleElement().satisfies(hasBeanOverrideHandler(
5656
field(SingleAnnotation.class, "message"), String.class, null));
5757
}
5858

5959
@Test
6060
void forTestClassWithMultipleFields() {
61-
List<BeanOverrideHandler> handlers = BeanOverrideHandler.forTestClass(MultipleAnnotations.class);
61+
List<BeanOverrideHandler> handlers = BeanOverrideTestUtils.findHandlers(MultipleAnnotations.class);
6262
assertThat(handlers).hasSize(2)
6363
.anySatisfy(hasBeanOverrideHandler(
6464
field(MultipleAnnotations.class, "message"), String.class, null))
@@ -68,7 +68,7 @@ void forTestClassWithMultipleFields() {
6868

6969
@Test
7070
void forTestClassWithMultipleFieldsWithIdenticalMetadata() {
71-
List<BeanOverrideHandler> handlers = BeanOverrideHandler.forTestClass(MultipleAnnotationsDuplicate.class);
71+
List<BeanOverrideHandler> handlers = BeanOverrideTestUtils.findHandlers(MultipleAnnotationsDuplicate.class);
7272
assertThat(handlers).hasSize(2)
7373
.anySatisfy(hasBeanOverrideHandler(
7474
field(MultipleAnnotationsDuplicate.class, "message1"), String.class, "messageBean"))
@@ -81,7 +81,7 @@ void forTestClassWithMultipleFieldsWithIdenticalMetadata() {
8181
void forTestClassWithCompetingBeanOverrideAnnotationsOnSameField() {
8282
Field faultyField = field(MultipleAnnotationsOnSameField.class, "message");
8383
assertThatIllegalStateException()
84-
.isThrownBy(() -> BeanOverrideHandler.forTestClass(MultipleAnnotationsOnSameField.class))
84+
.isThrownBy(() -> BeanOverrideTestUtils.findHandlers(MultipleAnnotationsOnSameField.class))
8585
.withMessageStartingWith("Multiple @BeanOverride annotations found")
8686
.withMessageContaining(faultyField.toString());
8787
}
@@ -90,7 +90,7 @@ void forTestClassWithCompetingBeanOverrideAnnotationsOnSameField() {
9090
void forTestClassWithStaticBeanOverrideField() {
9191
Field staticField = field(StaticBeanOverrideField.class, "message");
9292
assertThatIllegalStateException()
93-
.isThrownBy(() -> BeanOverrideHandler.forTestClass(StaticBeanOverrideField.class))
93+
.isThrownBy(() -> BeanOverrideTestUtils.findHandlers(StaticBeanOverrideField.class))
9494
.withMessage("@BeanOverride field must not be static: " + staticField);
9595
}
9696

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
* Copyright 2002-2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.test.context.bean.override;
18+
19+
import java.util.List;
20+
21+
/**
22+
* Test utilities for Bean Overrides.
23+
*
24+
* @author Sam Brannen
25+
* @since 6.2.2
26+
*/
27+
public abstract class BeanOverrideTestUtils {
28+
29+
public static List<BeanOverrideHandler> findHandlers(Class<?> testClass) {
30+
return BeanOverrideHandler.forTestClass(testClass);
31+
}
32+
33+
}

spring-test/src/test/java/org/springframework/test/context/bean/override/convention/TestBeanOverrideHandlerTests.java

+7-6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2024 the original author or authors.
2+
* Copyright 2002-2025 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.
@@ -26,6 +26,7 @@
2626
import org.springframework.core.ResolvableType;
2727
import org.springframework.test.context.bean.override.BeanOverrideHandler;
2828
import org.springframework.test.context.bean.override.BeanOverrideStrategy;
29+
import org.springframework.test.context.bean.override.BeanOverrideTestUtils;
2930
import org.springframework.util.ReflectionUtils;
3031
import org.springframework.util.StringUtils;
3132

@@ -42,21 +43,21 @@
4243
class TestBeanOverrideHandlerTests {
4344

4445
@Test
45-
void setsBeanNameToNullIfAnnotationNameIsNull() {
46-
List<BeanOverrideHandler> handlers = BeanOverrideHandler.forTestClass(SampleOneOverride.class);
46+
void beanNameIsSetToNullIfAnnotationNameIsEmpty() {
47+
List<BeanOverrideHandler> handlers = BeanOverrideTestUtils.findHandlers(SampleOneOverride.class);
4748
assertThat(handlers).singleElement().extracting(BeanOverrideHandler::getBeanName).isNull();
4849
}
4950

5051
@Test
51-
void setsBeanNameToAnnotationName() {
52-
List<BeanOverrideHandler> handlers = BeanOverrideHandler.forTestClass(SampleOneOverrideWithName.class);
52+
void beanNameIsSetToAnnotationName() {
53+
List<BeanOverrideHandler> handlers = BeanOverrideTestUtils.findHandlers(SampleOneOverrideWithName.class);
5354
assertThat(handlers).singleElement().extracting(BeanOverrideHandler::getBeanName).isEqualTo("anotherBean");
5455
}
5556

5657
@Test
5758
void failsWithMissingMethod() {
5859
assertThatIllegalStateException()
59-
.isThrownBy(() -> BeanOverrideHandler.forTestClass(SampleMissingMethod.class))
60+
.isThrownBy(() -> BeanOverrideTestUtils.findHandlers(SampleMissingMethod.class))
6061
.withMessage("No static method found named message() in %s with return type %s",
6162
SampleMissingMethod.class.getName(), String.class.getName());
6263
}

0 commit comments

Comments
 (0)