假设我使用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?或者也是唯一可能为主要实现类提供配置文件的解决方案?这是我试图避免的解决方案。
答案 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
注释中的一个配置文件。当然,在这个人为的例子中并不是非常有用,但是如果你想在不同的测试中使用三个或更多的配置文件,它会很好地扩展。