gpt4 book ai didi

Spring @Autowired 在测试中的行为与组件不同

转载 作者:行者123 更新时间:2023-12-04 13:30:30 24 4
gpt4 key购买 nike

@Autowired 周围的规则/行为编写测试时有什么不同?似乎通过测试,您可以自动连接到具体类型,但如果您在 @Component 中尝试相同的操作它会失败。这是一个人为的例子,但这是我遇到的,只是想更好地理解。

人为的示例代码:

public interface Gizmo {

void whirr();
}

@Configuration
public class GizmoConfiguration {

@Bean
@Profile("no-dependencies")
public Gizmo fooGizmoBean() {
return new FooGizmo();
}

@Bean
@Profile("!no-dependencies")
public Gizmo barGizmoBean() {
return new BarGizmo();
}

public class FooGizmo implements Gizmo {
@Override
public void whirr() {
}
}

public class BarGizmo implements Gizmo {
@Override
public void whirr() {
}
}
}

运行良好的测试:
@RunWith(SpringRunner.class)
@SpringBootTest
@ActiveProfiles(Application.Profiles.NO_DEPENDENCIES)
public class TestClass {

@Autowired
private GizmoConfiguration.FooGizmo gizmo;

@Test
public void test() {
assertNotNull(gizmo);
}
}

导致 java.lang.IllegalStateException: Failed to load ApplicationContext 的组件:
@Component
public class TestComponent {

@Autowired
private GizmoConfiguration.FooGizmo gizmo;
}

因为:
No qualifying bean of type 'GizmoConfiguration$FooGizmo' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

最佳答案

Are the rules/behaviors around @Autowired different when writing tests?



不完全是:规则实际上是完全一样的。不同之处在于 Spring 如何确定给定 bean 是否是 Autowiring 候选者的时间。

It seems that with a test, you can autowire to a concrete type, but if you try the same thing inside a @Component it will fail.



我理解你为什么会这样想,因为你的例子证明了这种行为,但你的分析并不完全正确。

所以让我解释一下...

当 Spring 尝试为您的 @Component 执行 Autowiring 时类,它拥有的关于来自 @Bean 的 bean 的类型(即类和接口(interface))的唯一信息方法是 @Bean 中可用的信息方法的正式签名。

在您的示例中,当 Spring 搜索所谓的“ Autowiring 候选者”以注入(inject)您的 @Component 时, Spring 只看到 Gizmo 类型的 bean为您的 fooGizmoBean() @Bean方法。这就是为什么您会看到“没有 'GizmoConfiguration$FooGizmo' 类型的合格 bean”错误,这恰好是完全正确的。

如果您希望 Spring 能够自动连接您的 @Component使用具体类型,您必须重新定义 fooGizmoBean() 的签名 @Bean返回方法 FooGizmo而不是 Gizmo .

所以,这就是故事的前半部分。故事的后半部分是为什么 Spring TestContext Framework 能够通过测试实例的具体类型执行 Autowiring 。

有效的原因是 ApplicationContext在测试框架尝试执行依赖注入(inject)时,它已经完全启动(即所有 bean 都已被实例化并且所有 @Bean 方法已被容器调用)。到那个时候, fooGizmoBean()方法已经被 Spring 调用,并且 Spring 现在知 Prop 体类型实际上是 FooGizmo .因此, @Autowired FooGizmo gizmo;在测试中工作。

关于Spring @Autowired 在测试中的行为与组件不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50991110/

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