Simplify Bean Override field injection logic

This commit simplifies the field injection logic for Bean Overrides in
order to align with the semantics of the core container and the Spring
TestContext Framework.

Closes gh-33677
This commit is contained in:
Sam Brannen 2024-10-09 15:41:24 +02:00
parent 4758424f6c
commit 381b16fba2
2 changed files with 4 additions and 20 deletions

View File

@ -89,14 +89,8 @@ class BeanOverrideRegistrar {
private void inject(Field field, Object target, String beanName) {
try {
ReflectionUtils.makeAccessible(field);
Object existingValue = ReflectionUtils.getField(field, target);
Object bean = this.beanFactory.getBean(beanName, field.getType());
if (existingValue == bean) {
return;
}
Assert.state(existingValue == null, () -> "The existing value '" + existingValue +
"' of field '" + field + "' is not the same as the new value '" + bean + "'");
ReflectionUtils.makeAccessible(field);
ReflectionUtils.setField(field, target, bean);
}
catch (Throwable ex) {

View File

@ -16,13 +16,11 @@
package org.springframework.test.context.bean.override;
import java.lang.reflect.Field;
import java.util.List;
import org.springframework.test.context.TestContext;
import org.springframework.test.context.support.AbstractTestExecutionListener;
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
import org.springframework.util.ReflectionUtils;
/**
* {@code TestExecutionListener} that enables {@link BeanOverride @BeanOverride}
@ -50,7 +48,7 @@ public class BeanOverrideTestExecutionListener extends AbstractTestExecutionList
*/
@Override
public void prepareTestInstance(TestContext testContext) throws Exception {
injectFields(testContext, false);
injectFields(testContext);
}
/**
@ -67,18 +65,15 @@ public class BeanOverrideTestExecutionListener extends AbstractTestExecutionList
Object reinjectDependenciesAttribute = testContext.getAttribute(
DependencyInjectionTestExecutionListener.REINJECT_DEPENDENCIES_ATTRIBUTE);
if (Boolean.TRUE.equals(reinjectDependenciesAttribute)) {
injectFields(testContext, true);
injectFields(testContext);
}
}
/**
* Inject each {@link BeanOverride @BeanOverride} field in the test instance with
* a corresponding bean override instance.
* <p>If the {@code reinjectFields} flag is {@code true} (which indicates that
* a fresh instance is required), the field is nulled out before injecting
* the overridden bean instance.
*/
private static void injectFields(TestContext testContext, boolean reinjectFields) {
private static void injectFields(TestContext testContext) {
List<OverrideMetadata> overrideMetadataList = OverrideMetadata.forTestClass(testContext.getTestClass());
if (!overrideMetadataList.isEmpty()) {
Object testInstance = testContext.getTestInstance();
@ -86,11 +81,6 @@ public class BeanOverrideTestExecutionListener extends AbstractTestExecutionList
.getBean(BeanOverrideContextCustomizer.REGISTRAR_BEAN_NAME, BeanOverrideRegistrar.class);
for (OverrideMetadata overrideMetadata : overrideMetadataList) {
if (reinjectFields) {
Field field = overrideMetadata.getField();
ReflectionUtils.makeAccessible(field);
ReflectionUtils.setField(field, testInstance, null);
}
registrar.inject(testInstance, overrideMetadata);
}
}