提问者:小点点

在bean配置方法上使用@Profile注释时,无法注入同一接口的两个字段


我使用Spring 5.1.4。RELEASE,在bean配置方法上使用@Profile注释时,无法通过构造函数注入相同接口的两个字段。我有一个简单的Publisher组件,如下所示:

@Component
public class Publisher {

    private final MyClient prodClient;
    private final MyClient testClient;

    @java.beans.ConstructorProperties({"prodClient", "testClient"})
    public Publisher(MyClient prodClient, MyClient testClient) {
        this.prodClient = prodClient;
        this.testClient = testClient;
    }

}

当我使用@Profile注释标记整个配置时,它会按预期工作:

@Profile(Profiles.MY_CLIENT)
@Configuration
public class ClientConfig {

    @Bean
    public MyClient prodClient() {
        return new HttpClient("prod.client.channel");
    }

    @Bean
    public MyClient testClient() {
        return new HttpClient("test.client.channel");
    }
}

上面的配置是可以的,但是当我只想在配置类中的某些方法上使用@Profile注释时就会出现问题:

@Configuration
public class ClientConfig {

    @Profile(Profiles.MY_CLIENT)
    @Bean
    public MyClient prodClient() {
        return new HttpClient();
    }

    @Profile(Profiles.MY_CLIENT)
    @Bean
    public MyClient testClient() {
        return new HttpClient();
    }

    // some other beans...
}

然后我在启动过程中出错:

***************************
APPLICATION FAILED TO START
***************************

Description:

Parameter 0 of constructor in com.test.Publisher required a bean of type 'com.test.MyClient' that could not be found.

更新:已经解决了。这是我的错误。我有另外两个bean方法用不同的@Profile注释用于集成测试,但是它们对生产代码具有相同的名称(用Profile注释。MY_CLIENT配置文件):

@Configuration
public class ClientConfig {

    @Profile(Profiles.MY_CLIENT)
    @Bean
    public MyClient prodClient() {
        return new HttpClient();
    }

    @Profile(Profiles.MY_CLIENT)
    @Bean
    public MyClient testClient() {
        return new HttpClient();
    }

    // ... other beans

    @Profile(Profiles.MOCK_MY_CLIENT)
    @Bean
    public MyClient prodClient() {
        return new MockClient();
    }

    @Profile(Profiles.MOCK_MY_CLIENT)
    @Bean
    public MyClient testClient() {
        return new MockClient();
    }
}

共2个答案

匿名用户

嗯,如果你尝试注入这个组件的列表?类似于

public Publisher(List<MyClient> clients) {

}

在客户端实现中,您设置了一个标志,该标志可能有助于了解何时应该使用它。

匿名用户

在此代码中:

@java.beans.ConstructorProperties({"prodClient", "testClient"})
public Publisher(MyClient prodClient, MyClient testClient) {
    this.prodClient = prodClient;
    this.testClient = testClient;
}

尝试在参数上使用@Autowired注释:

public Publisher(@Autowired MyClient prodClient, @Autowired MyClient testClient) {
    this.prodClient = prodClient;
    this.testClient = testClient;
}