Skip to content

Commit 8172d7a

Browse files
committed
Polish
1 parent 6b64e99 commit 8172d7a

File tree

7 files changed

+99
-62
lines changed

7 files changed

+99
-62
lines changed

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,12 +100,12 @@ private void parseField(Field field, Class<?> source) {
100100
MergedAnnotations.from(field, MergedAnnotations.SearchStrategy.DIRECT)
101101
.stream(BeanOverride.class)
102102
.map(bo -> {
103-
var a = bo.getMetaSource();
103+
MergedAnnotation<?> a = bo.getMetaSource();
104104
Assert.notNull(a, "BeanOverride annotation must be meta-present");
105105
return new AnnotationPair(a.synthesize(), bo);
106106
})
107107
.forEach(pair -> {
108-
var metaAnnotation = pair.metaAnnotation().synthesize();
108+
BeanOverride metaAnnotation = pair.metaAnnotation().synthesize();
109109
final BeanOverrideProcessor processor = getProcessorInstance(metaAnnotation.value());
110110
if (processor == null) {
111111
return;

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@
2626

2727
/**
2828
* An interface for Bean Overriding concrete processing.
29-
* Processors are generally linked to one or more specific concrete annotations
29+
*
30+
* <p>Processors are generally linked to one or more specific concrete annotations
3031
* (meta-annotated with {@link BeanOverride}) and specify different steps in the
3132
* process of parsing these annotations, ultimately creating
3233
* {@link OverrideMetadata} which will be used to instantiate the overrides.
@@ -57,8 +58,8 @@ default ResolvableType getOrDeduceType(Field field, Annotation annotation, Class
5758
* {@link #getOrDeduceType(Field, Annotation, Class) type}.
5859
* Specific implementations of metadata can have state to be used during
5960
* override {@link OverrideMetadata#createOverride(String, BeanDefinition,
60-
* Object) instance creation} (e.g. from further parsing the annotation or
61-
* the annotated field).
61+
* Object) instance creation}, that is from further parsing the annotation or
62+
* the annotated field.
6263
* @param field the annotated field
6364
* @param overrideAnnotation the field annotation
6465
* @param typeToOverride the target type

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

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,20 +26,23 @@
2626
public enum BeanOverrideStrategy {
2727

2828
/**
29-
* Replace a given bean's definition, immediately preparing a singleton
29+
* Replace a given bean definition, immediately preparing a singleton
3030
* instance. Enforces the original bean definition to exist.
3131
*/
3232
REPLACE_DEFINITION,
33+
3334
/**
34-
* Replace a given bean's definition, immediately preparing a singleton
35+
* Replace a given bean definition, immediately preparing a singleton
3536
* instance. If the original bean definition does not exist, create the
3637
* override definition instead of failing.
3738
*/
3839
REPLACE_OR_CREATE_DEFINITION,
40+
3941
/**
4042
* Intercept and wrap the actual bean instance upon creation, during
4143
* {@link org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostProcessor#getEarlyBeanReference(Object, String)
4244
* early bean definition}.
4345
*/
44-
WRAP_EARLY_BEAN;
46+
WRAP_EARLY_BEAN
47+
4548
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@
2626
import org.springframework.util.ReflectionUtils;
2727

2828
/**
29-
* A {@link TestExecutionListener} that enables Bean Override support in
30-
* tests, injecting overridden beans in appropriate fields.
29+
* A {@link TestExecutionListener} implementation that enables Bean Override
30+
* support in tests, injecting overridden beans in appropriate fields.
3131
*
3232
* <p>Some flavors of Bean Override might additionally require the use of
3333
* additional listeners, which should be mentioned in the annotation(s) javadoc.

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

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,14 @@
3434
public abstract class OverrideMetadata {
3535

3636
private final Field field;
37+
3738
private final Annotation overrideAnnotation;
39+
3840
private final ResolvableType typeToOverride;
41+
3942
private final BeanOverrideStrategy strategy;
4043

41-
public OverrideMetadata(Field field, Annotation overrideAnnotation,
44+
protected OverrideMetadata(Field field, Annotation overrideAnnotation,
4245
ResolvableType typeToOverride, BeanOverrideStrategy strategy) {
4346
this.field = field;
4447
this.overrideAnnotation = overrideAnnotation;
@@ -47,50 +50,46 @@ public OverrideMetadata(Field field, Annotation overrideAnnotation,
4750
}
4851

4952
/**
50-
* Define a short human-readable description of the kind of override this
51-
* OverrideMetadata is about. This is especially useful for
52-
* {@link BeanOverrideProcessor} that produce several subtypes of metadata
53-
* (e.g. "mock" vs "spy").
53+
* Return a short human-readable description of the kind of override this
54+
* instance handles.
5455
*/
5556
public abstract String getBeanOverrideDescription();
5657

5758
/**
58-
* Provide the expected bean name to override. Typically, this is either
59+
* Return the expected bean name to override. Typically, this is either
5960
* explicitly set in the concrete annotations or defined by the annotated
6061
* field's name.
61-
* @return the expected bean name, not null
62+
* @return the expected bean name
6263
*/
6364
protected String getExpectedBeanName() {
6465
return this.field.getName();
6566
}
6667

6768
/**
68-
* The field annotated with a {@link BeanOverride}-compatible annotation.
69-
* @return the annotated field
69+
* Return the annotated {@link Field}.
7070
*/
7171
public Field field() {
7272
return this.field;
7373
}
7474

7575
/**
76-
* The concrete override annotation, i.e. the one meta-annotated with
77-
* {@link BeanOverride}.
76+
* Return the concrete override annotation, that is the one meta-annotated
77+
* with {@link BeanOverride}.
7878
*/
7979
public Annotation overrideAnnotation() {
8080
return this.overrideAnnotation;
8181
}
8282

8383
/**
84-
* The type to override, as a {@link ResolvableType}.
84+
* Return the bean {@link ResolvableType type} to override.
8585
*/
8686
public ResolvableType typeToOverride() {
8787
return this.typeToOverride;
8888
}
8989

9090
/**
91-
* Define the broad {@link BeanOverrideStrategy} for this
92-
* {@link OverrideMetadata}, as a hint on how and when the override instance
93-
* should be created.
91+
* Return the {@link BeanOverrideStrategy} for this instance, as a hint on
92+
* how and when the override instance should be created.
9493
*/
9594
public final BeanOverrideStrategy getBeanOverrideStrategy() {
9695
return this.strategy;
@@ -99,7 +98,7 @@ public final BeanOverrideStrategy getBeanOverrideStrategy() {
9998
/**
10099
* Create an override instance from this {@link OverrideMetadata},
101100
* optionally provided with an existing {@link BeanDefinition} and/or an
102-
* original instance (i.e. a singleton or an early wrapped instance).
101+
* original instance, that is a singleton or an early wrapped instance.
103102
* @param beanName the name of the bean being overridden
104103
* @param existingBeanDefinition an existing bean definition for that bean
105104
* name, or {@code null} if not relevant
@@ -129,7 +128,7 @@ public boolean equals(Object obj) {
129128
if (obj == null || !getClass().isAssignableFrom(obj.getClass())) {
130129
return false;
131130
}
132-
var that = (OverrideMetadata) obj;
131+
OverrideMetadata that = (OverrideMetadata) obj;
133132
return Objects.equals(this.field, that.field) &&
134133
Objects.equals(this.overrideAnnotation, that.overrideAnnotation) &&
135134
Objects.equals(this.strategy, that.strategy) &&

spring-test/src/main/java/org/springframework/test/bean/override/convention/TestBean.java

Lines changed: 59 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -25,29 +25,63 @@
2525
import org.springframework.test.bean.override.BeanOverride;
2626

2727
/**
28-
* Mark a field to represent a "method" bean override of the bean of the same
29-
* name and inject the field with the overriding instance.
28+
* Mark a field to override a bean instance in the {@code BeanFactory}.
3029
*
31-
* <p>The instance is created from a static method in the declaring class which
32-
* return type is compatible with the annotated field and which name follows the
33-
* convention:
30+
* <p>The instance is created from a no-arg static method in the declaring
31+
* class whose return type is compatible with the annotated field. The method
32+
* is deduced as follows:
3433
* <ul>
35-
* <li>if the annotation's {@link #methodName()} is specified,
36-
* look for that one.</li>
37-
* <li>if not, look for exactly one method named with the
38-
* {@link #CONVENTION_SUFFIX} suffix and either:</li>
39-
* <ul>
40-
* <li>starting with the annotated field name</li>
41-
* <li>starting with the bean name</li>
42-
* </ul>
34+
* <li>if the {@link #methodName()} is specified, look for a static method with
35+
* that name.</li>
36+
* <li>if not, look for exactly one static method named with a suffix equal to
37+
* {@value #CONVENTION_SUFFIX} and either starting with the annotated field
38+
* name, or starting with the bean name.</li>
4339
* </ul>
4440
*
45-
* <p>The annotated field's name is interpreted to be the name of the original
46-
* bean to override, unless the annotation's {@link #name()} is specified.
41+
* <p>Consider the following example:
42+
*
43+
* <pre><code>
44+
* class CustomerServiceTests {
45+
*
46+
* &#064;TestBean
47+
* private CustomerRepository repository;
48+
*
49+
* // Tests
50+
*
51+
* private static CustomerRepository repositoryTestOverride() {
52+
* return new TestCustomerRepository();
53+
* }
54+
* }</code></pre>
55+
*
56+
* <p>In the example above, the {@code repository} bean is replaced by the
57+
* instance generated by the {@code repositoryTestOverride} method. Not only
58+
* the overridden instance is injected in the {@code repository} field, but it
59+
* is also replaced in the {@code BeanFactory} so that other injection points
60+
* for that bean use the override.
61+
*
62+
* <p>To make things more explicit, the method name can be set, as shown in the
63+
* following example:
64+
*
65+
* <pre><code>
66+
* class CustomerServiceTests {
67+
*
68+
* &#064;TestBean(methodName = "createTestCustomerRepository")
69+
* private CustomerRepository repository;
70+
*
71+
* // Tests
72+
*
73+
* private static CustomerRepository createTestCustomerRepository() {
74+
* return new TestCustomerRepository();
75+
* }
76+
* }</code></pre>
77+
*
78+
* <p>By default, the name of the bean is inferred from the name of the annotated
79+
* field. To use a different bean name, set the {@link #name()} property.
4780
*
48-
* @see TestBeanOverrideProcessor
4981
* @author Simon Baslé
82+
* @author Stephane Nicoll
5083
* @since 6.2
84+
* @see TestBeanOverrideProcessor
5185
*/
5286
@Target(ElementType.FIELD)
5387
@Retention(RetentionPolicy.RUNTIME)
@@ -56,23 +90,23 @@
5690
public @interface TestBean {
5791

5892
/**
59-
* The method suffix expected as a convention in static methods which
60-
* provides an override instance.
93+
* Required suffix for a method that overrides a bean instance that is
94+
* detected by convention.
6195
*/
6296
String CONVENTION_SUFFIX = "TestOverride";
6397

6498
/**
65-
* The name of a static method to look for in the Configuration, which will
66-
* be used to instantiate the override bean and inject the annotated field.
67-
* <p> Default is {@code ""} (the empty String), which is translated into
68-
* the annotated field's name concatenated with the
69-
* {@link #CONVENTION_SUFFIX}.
99+
* Name of a static method to look for in the test, which will be used to
100+
* instantiate the bean to override.
101+
* <p>Default to {@code ""} (the empty String), which detects the method
102+
* to us by convention.
70103
*/
71104
String methodName() default "";
72105

73106
/**
74-
* The name of the original bean to override, or {@code ""} (the empty
75-
* String) to deduce the name from the annotated field.
107+
* Name of the bean to override.
108+
* <p>Default to {@code ""} (the empty String) to use the name of the
109+
* annotated field.
76110
*/
77111
String name() default "";
78112
}

spring-test/src/main/java/org/springframework/test/bean/override/convention/TestBeanOverrideProcessor.java

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
import java.util.LinkedHashSet;
2626
import java.util.List;
2727
import java.util.Set;
28-
import java.util.stream.Collectors;
2928

3029
import org.springframework.beans.factory.config.BeanDefinition;
3130
import org.springframework.core.ResolvableType;
@@ -37,8 +36,8 @@
3736
import org.springframework.util.StringUtils;
3837

3938
/**
40-
* Simple {@link BeanOverrideProcessor} primarily made to work with the
41-
* {@link TestBean} annotation but can work with arbitrary override annotations
39+
* {@link BeanOverrideProcessor} implementation primarily made to work with
40+
* {@link TestBean @TestBean}, but can work with arbitrary override annotations
4241
* provided the annotated class has a relevant method according to the
4342
* convention documented in {@link TestBean}.
4443
*
@@ -48,19 +47,20 @@
4847
public class TestBeanOverrideProcessor implements BeanOverrideProcessor {
4948

5049
/**
51-
* Ensures the {@code enclosingClass} has a static, no-arguments method with
52-
* the provided {@code expectedMethodReturnType} and exactly one of the
50+
* Ensure the given {@code enclosingClass} has a static, no-arguments method
51+
* with the given {@code expectedMethodReturnType} and exactly one of the
5352
* {@code expectedMethodNames}.
5453
*/
5554
public static Method ensureMethod(Class<?> enclosingClass, Class<?> expectedMethodReturnType,
5655
String... expectedMethodNames) {
56+
5757
Assert.isTrue(expectedMethodNames.length > 0, "At least one expectedMethodName is required");
5858
Set<String> expectedNames = new LinkedHashSet<>(Arrays.asList(expectedMethodNames));
5959
final List<Method> found = Arrays.stream(enclosingClass.getDeclaredMethods())
60-
.filter(m -> Modifier.isStatic(m.getModifiers()))
61-
.filter(m -> expectedNames.contains(m.getName()) && expectedMethodReturnType
62-
.isAssignableFrom(m.getReturnType()))
63-
.collect(Collectors.toList());
60+
.filter(method -> Modifier.isStatic(method.getModifiers()))
61+
.filter(method -> expectedNames.contains(method.getName())
62+
&& expectedMethodReturnType.isAssignableFrom(method.getReturnType()))
63+
.toList();
6464

6565
Assert.state(found.size() == 1, () -> "Found " + found.size() + " static methods " +
6666
"instead of exactly one, matching a name in " + expectedNames + " with return type " +
@@ -87,7 +87,7 @@ public OverrideMetadata createMetadata(Field field, Annotation overrideAnnotatio
8787
}
8888
// otherwise defer the resolution of the static method until OverrideMetadata#createOverride
8989
return new MethodConventionOverrideMetadata(field, null, null, overrideAnnotation,
90-
typeToOverride);
90+
typeToOverride);
9191
}
9292

9393
static final class MethodConventionOverrideMetadata extends OverrideMetadata {

0 commit comments

Comments
 (0)