有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java为什么Spring@Qualifier不能与Spock和Spring Boot一起使用

我正在试着为斯波克的控制器写一个测试

@ContextConfiguration(loader = SpringApplicationContextLoader.class,
    classes = [Application.class, CreateUserControllerTest.class])
@WebAppConfiguration
@Configuration
class CreateUserControllerTest extends Specification {

    @Autowired
    @Qualifier("ble")
    PasswordEncryptor passwordEncryptor

    @Autowired
    UserRepository userRepository

    @Autowired
    WebApplicationContext context

    @Autowired
    CreateUserController testedInstance

    def "Injection works"() {
        expect:
        testedInstance instanceof CreateUserController
        userRepository != null
    }

    @Bean
    public UserRepository userRepository() {
        return Mock(UserRepository.class)
    }

    @Bean(name = "ble")
    PasswordEncryptor passwordEncryptor() {
        return Mock(PasswordEncryptor)
    }

}

应用程序类只是Spring Boot最简单的配置(启用自动扫描)。它提供了一个密码加密程序。我想用提供模拟的bean替换应用程序中的这个bean

但不幸的是,Spring抛出了一个NonuniqueBeandDefinitionException:

Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [org.jasypt.util.password.PasswordEncryptor] is defined: expected single matching bean but found 2: provide,ble
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1054)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:942)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:533)
... 54 more

@Qualifier注释似乎根本不起作用。我能做什么

编辑

问题不在于CreateUserControllerTest,而在于CreateUserController

public class CreateUserController {
    @Autowired
    private PasswordEncryptor encryptor;
}

没有@Qualifier注释,因此Spring不知道应该注入哪个bean。不幸的是,我不知道如何让Spring用本地配置替换应用程序中的PasswordEncryptorbean


共 (1) 个答案

  1. # 1 楼答案

    @Qualifier是连接bean的一个特定实例,如果您有同一接口的多个实现

    但在spring上下文中,每个bean仍然需要一个“唯一”的名称

    因此,您正在尝试注册两个名为“passwordEncryptor”的bean。一个在测试中,另一个似乎在实际代码“Application.class”中

    如果要模拟“PasswordEncryptor”,请使用@Mock@Spy。(或)如果要避免错误,请更改方法的名称以避免实例名称冲突

    @Mock
    private PasswordEncryptor passwordEncryptor;
    
    or
    
    @Spy
    private PasswordEncryptor passwordEncryptor;
    

    编辑

    该错误的另一种可能性是,在代码中的某个地方,您为“passwordEncryptor”定义了一个@Autowired而没有@Qualifier标记

    但是

    您定义了@Bean(name="...") passwordEncryptor的两个实例,因此Spring上下文在选择哪个实例来“自动连接”字段时比较混乱