gpt4 book ai didi

spring - 为什么@SpringBootTest在构造函数注入(inject)中需要@Autowired

转载 作者:行者123 更新时间:2023-12-05 02:01:20 24 4
gpt4 key购买 nike

一个更笼统的问题。如果在常规的 Spring 托管类中使用构造函数注入(inject),则类将 Autowiring 而不需要 @Autowired 注释,即。即:

@Service
class MailService(
private val projectService: ProjectService,
private val mailer: Mailer
) { ... }

在@SpringBootTest类中遵循相同的构造函数注入(inject)原则,您需要将@Autowired注解设置为构造函数参数,否则将无法注入(inject)该类,即。即:

@SpringBootTest
internal class MailerTest(
@Autowired private val mailer: Mailer
) { ... }

为什么会出现这种差异?

最佳答案

对于 SpringBoot 应用程序,spring 负责连接 bean。

在 JUnit 5 的情况下,必须将 Spring 管理的 Beans 注入(inject)到 JUnit 管理的测试类实例中。幸运的是,JUnit 5 提供了一种通过 ParameterResolver 来做到这一点的方法。 .

@SpringBootTest 注册 SpringExtension,它在其他功能中用作 ParameterResolver:

@Override
public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) {
Parameter parameter = parameterContext.getParameter();
Executable executable = parameter.getDeclaringExecutable();
Class<?> testClass = extensionContext.getRequiredTestClass();
PropertyProvider junitPropertyProvider = propertyName ->
extensionContext.getConfigurationParameter(propertyName).orElse(null);
return (TestConstructorUtils.isAutowirableConstructor(executable, testClass, junitPropertyProvider) ||
ApplicationContext.class.isAssignableFrom(parameter.getType()) ||
supportsApplicationEvents(parameterContext) ||
ParameterResolutionDelegate.isAutowirable(parameter, parameterContext.getIndex()));
}

ParameterResolutionDelegate.isAutowirable 依靠注解来确定是否可以从 Spring 的 ApplicationContext 中注入(inject)参数

public static boolean isAutowirable(Parameter parameter, int parameterIndex) {
Assert.notNull(parameter, "Parameter must not be null");
AnnotatedElement annotatedParameter = getEffectiveAnnotatedParameter(parameter, parameterIndex);
return (AnnotatedElementUtils.hasAnnotation(annotatedParameter, Autowired.class) ||
AnnotatedElementUtils.hasAnnotation(annotatedParameter, Qualifier.class) ||
AnnotatedElementUtils.hasAnnotation(annotatedParameter, Value.class));
}

事实上,如果省略@Autowired注解,JUnit会提示缺少ParameterResolver:

org.junit.jupiter.api.extension.ParameterResolutionException: No ParameterResolver registered for parameter [test.Mailer mailer] in constructor [public test.MailServiceTest(test.Mailer)].

关于spring - 为什么@SpringBootTest在构造函数注入(inject)中需要@Autowired,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66671846/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com