Skip to content

Commit 0ef5a40

Browse files
committed
Support non-public BeanOverrideProcessors in the TestContext framework
Closes gh-32485
1 parent 6df2764 commit 0ef5a40

File tree

4 files changed

+15
-35
lines changed

4 files changed

+15
-35
lines changed

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

+7-30
Original file line numberDiff line numberDiff line change
@@ -17,21 +17,17 @@
1717
package org.springframework.test.context.bean.override;
1818

1919
import java.lang.annotation.Annotation;
20-
import java.lang.reflect.Constructor;
2120
import java.lang.reflect.Field;
22-
import java.lang.reflect.InvocationTargetException;
2321
import java.util.Collections;
2422
import java.util.LinkedHashSet;
2523
import java.util.Set;
2624
import java.util.concurrent.atomic.AtomicBoolean;
2725

28-
import org.springframework.beans.factory.support.BeanDefinitionValidationException;
26+
import org.springframework.beans.BeanUtils;
2927
import org.springframework.core.ResolvableType;
3028
import org.springframework.core.annotation.MergedAnnotation;
3129
import org.springframework.core.annotation.MergedAnnotations;
32-
import org.springframework.lang.Nullable;
3330
import org.springframework.util.Assert;
34-
import org.springframework.util.ClassUtils;
3531
import org.springframework.util.ReflectionUtils;
3632

3733
import static org.springframework.core.annotation.MergedAnnotations.SearchStrategy.DIRECT;
@@ -41,6 +37,7 @@
4137
* on fields of a given class and creates {@link OverrideMetadata} accordingly.
4238
*
4339
* @author Simon Baslé
40+
* @author Sam Brannen
4441
* @since 6.2
4542
*/
4643
class BeanOverrideParser {
@@ -102,41 +99,21 @@ private void parseField(Field field, Class<?> source) {
10299
.map(mergedAnnotation -> {
103100
MergedAnnotation<?> metaSource = mergedAnnotation.getMetaSource();
104101
Assert.notNull(metaSource, "@BeanOverride annotation must be meta-present");
105-
return new AnnotationPair(metaSource.synthesize(), mergedAnnotation);
102+
return new AnnotationPair(metaSource.synthesize(), mergedAnnotation.synthesize());
106103
})
107104
.forEach(pair -> {
108-
BeanOverride beanOverride = pair.mergedAnnotation().synthesize();
109-
BeanOverrideProcessor processor = getProcessorInstance(beanOverride.value());
110-
if (processor == null) {
111-
return;
112-
}
113-
ResolvableType typeToOverride = processor.getOrDeduceType(field, pair.annotation(), source);
105+
BeanOverrideProcessor processor = BeanUtils.instantiateClass(pair.beanOverride.value());
106+
ResolvableType typeToOverride = processor.getOrDeduceType(field, pair.composedAnnotation, source);
114107

115108
Assert.state(overrideAnnotationFound.compareAndSet(false, true),
116109
() -> "Multiple @BeanOverride annotations found on field: " + field);
117-
OverrideMetadata metadata = processor.createMetadata(field, pair.annotation(), typeToOverride);
110+
OverrideMetadata metadata = processor.createMetadata(field, pair.composedAnnotation, typeToOverride);
118111
boolean isNewDefinition = this.parsedMetadata.add(metadata);
119112
Assert.state(isNewDefinition, () -> "Duplicate " + metadata.getBeanOverrideDescription() +
120113
" OverrideMetadata: " + metadata);
121114
});
122115
}
123116

124-
@Nullable
125-
private BeanOverrideProcessor getProcessorInstance(Class<? extends BeanOverrideProcessor> processorClass) {
126-
Constructor<? extends BeanOverrideProcessor> constructor = ClassUtils.getConstructorIfAvailable(processorClass);
127-
if (constructor != null) {
128-
try {
129-
ReflectionUtils.makeAccessible(constructor);
130-
return constructor.newInstance();
131-
}
132-
catch (InstantiationException | IllegalAccessException | InvocationTargetException ex) {
133-
throw new BeanDefinitionValidationException(
134-
"Failed to instantiate BeanOverrideProcessor of type " + processorClass.getName(), ex);
135-
}
136-
}
137-
return null;
138-
}
139-
140-
private record AnnotationPair(Annotation annotation, MergedAnnotation<BeanOverride> mergedAnnotation) {}
117+
private record AnnotationPair(Annotation composedAnnotation, BeanOverride beanOverride) {}
141118

142119
}

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

+3-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626

2727
import static org.assertj.core.api.Assertions.assertThat;
2828
import static org.assertj.core.api.Assertions.assertThatRuntimeException;
29-
import static org.springframework.test.context.bean.override.example.ExampleBeanOverrideProcessor.DUPLICATE_TRIGGER;
3029

3130
/**
3231
* Unit tests for {@link BeanOverrideParser}.
@@ -35,6 +34,9 @@
3534
*/
3635
class BeanOverrideParserTests {
3736

37+
// Copy of ExampleBeanOverrideProcessor.DUPLICATE_TRIGGER which is package-private.
38+
private static final String DUPLICATE_TRIGGER = "DUPLICATE";
39+
3840
private final BeanOverrideParser parser = new BeanOverrideParser();
3941

4042

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

+4-3
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,10 @@
2323
import org.springframework.test.context.bean.override.BeanOverrideProcessor;
2424
import org.springframework.test.context.bean.override.OverrideMetadata;
2525

26-
public class ExampleBeanOverrideProcessor implements BeanOverrideProcessor {
26+
// Intentionally NOT public
27+
class ExampleBeanOverrideProcessor implements BeanOverrideProcessor {
28+
29+
static final String DUPLICATE_TRIGGER = "DUPLICATE";
2730

2831
private static final TestOverrideMetadata CONSTANT = new TestOverrideMetadata() {
2932
@Override
@@ -32,8 +35,6 @@ public String toString() {
3235
}
3336
};
3437

35-
public static final String DUPLICATE_TRIGGER = "CONSTANT";
36-
3738
@Override
3839
public OverrideMetadata createMetadata(Field field, Annotation overrideAnnotation, ResolvableType typeToOverride) {
3940
if (!(overrideAnnotation instanceof ExampleBeanOverrideAnnotation annotation)) {

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232

3333
import static org.springframework.test.context.bean.override.example.ExampleBeanOverrideAnnotation.DEFAULT_VALUE;
3434

35-
public class TestOverrideMetadata extends OverrideMetadata {
35+
class TestOverrideMetadata extends OverrideMetadata {
3636

3737
@Nullable
3838
private final Method method;

0 commit comments

Comments
 (0)