将弹簧与junit一起使用时的行为不同

问题描述

我使用spring 5,我发现当我将其用于测试(与junit 5)和主代码中时,spring的行为有所不同。最主要的是,当我使用spring进行测试时,该单例未在启动期间初始化。

例如,这是我的代码

@Component
@Scope(value = Configurablebeanfactory.ScopE_SINGLetoN)
public class Foo<T> {

    public Foo(Class<T> someClass) {
         //...
    }
}

可以看出,该类在构造函数中需要参数,因此我手动创建了它的实例-context.getBean(....)。在测试中使用此类时-一切正常。但是,当我在主代码中使用它时,我会在春季启动时获得:

NoSuchBeanDeFinitionException: No qualifying bean of type 'java.lang.class<?>' available: expected at least 1 bean which qualifies as autowire candidate.

这是我的测试示例:

@ExtendWith({SpringExtension.class})
@ContextConfiguration(classes = ContextConfig.class)
public class TestIT {}

如何解释这种不同的行为?我在春季没有太多经验,所以感谢您的帮助。

解决方法

NoSuchBeanDefinitionException意味着Spring不能在ApplicationContext中找到所需的bean。根据您的@Component类Foo,您可以使用以下选项:

  • 创建一个Type类的bean,以便Spring可以找到它。
  • 删除Foo的构造函数,然后使用setter方法设置参数someClass。
  • 创建一个没有参数的构造函数,并实例化该构造函数内部的someClass。

在不知道有关someClass的详细信息的情况下,我无法说出什么是最佳选择。

在我的德语博客中,有一篇关于Spring Basics:Beans和依赖注入的文章,它解释了您尝试做的理论:
https://agile-coding.blogspot.com/2020/10/kernkonzepte-von-spring-beans-und.html

PS:单例是每个Spring Bean的默认作用域,您可以删除@Scope注释。