为什么@springboottest需要@autowired在构造函数注入中

x33g5p2x  于 2021-07-16  发布在  Java
关注(0)|答案(1)|浏览(523)

一个更一般的问题。如果在常规spring管理的类中使用构造函数注入,那么这些类将自动连接,而不需要@autowired注解,即。e、 地址:

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

在@springboottest类中遵循相同的构造函数注入原则,您需要将@autowired注解设置为构造函数参数,否则它将无法注入类,即。e、 地址:

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

为什么会出现这种差异?

d4so4syb

d4so4syb1#

在springboot应用程序中,spring负责连接bean。
对于JUnit5,必须将spring管理的bean注入junit管理的测试类示例。幸运的是,JUnit5提供了一种通过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注入参数

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)].

相关问题