弹簧轮廓注射:不要在没有轮廓的情况下注射一个类

时间:2014-07-16 15:01:54

标签: java spring spring-mvc dependency-injection

假设我使用Spring作为我的Java项目,我有以下接口和类:

public interface MyInterface { ... }

@Component
public class MyInterfaceMainImpl implements MyInterface { ... }

@Component
@Profile("mock")
public class MyInterfaceMockImpl implements MyInterface { ... }

@ContextConfiguration(locations = {"classpath:my-context.xml"})
@ActiveProfiles(profiles = {"mock"})
public class MyInterfaceTest extends AbstractTestNGSpringContextTests {
    @Inject
    private MyInterface myInterface;
    ...
}

假设 my-context.xml 允许在包含我的接口及其实现类的包上进行组件扫描。当我将配置文件指定为“mock”时,我收到一个错误,上面写着这样的内容:“预期的单个匹配bean但找到2:......”。

任何想法如何避免让我的非配置文件方法在注入期间成为匹配的bean?或者也是唯一可能为主要实现类提供配置文件的解决方案?这是我试图避免的解决方案。

3 个答案:

答案 0 :(得分:4)

有两种选择:

  • 使用@Primary表示当两种实现都存在时,MyInterfaceMockImpl是首选:

    @Component
    @Primary
    @Profile("mock")
    public class MyInterfaceMockImpl implements MyInterface { ... }
    
  • @Profile处于有效状态时,使用mock否定来排除主要实施:

    @Component
    @Profile("!mock")
    public class MyInterfaceMainImpl implements MyInterface { ... }
    

答案 1 :(得分:2)

您也可以使用@Qualifier指定哪一个

@Component("main")
public class MyInterfaceMainImpl implements MyInterface { ... }

@Component("mock")
public class MyInterfaceMockImpl implements MyInterface { ... }



@Inject
@Qualifer("mock")
private MyInterface myInterface;

答案 2 :(得分:1)

另一种选择是用@Profile注释两个实现,并为每个实现提供不同的名称。

@Component 
@Profile("mock")
public class MyInterfaceMockImpl implements MyInterface { ... }

@Component
@Profile("default")
public class MyInterfaceMainImpl implements MyInterface { ... }

这种方法的优点是,它允许您将default指定为测试类@ActiveProfiles注释中的一个配置文件。当然,在这个人为的例子中并不是非常有用,但是如果你想在不同的测试中使用三个或更多的配置文件,它会很好地扩展。

相关问题