我尝试通过阅读Spring in action 4来提高我的Spring知识。 当我要分段,描述使用限定符注释(3.3.2)时,我遇到了问题。 为了测试这个注释的作用,我编写了Dessert接口,它由3个类实现,使用@Component注释在上下文中创建。 我还创建了类Taster,它“尝试”一些甜点,由一些限定符自动装配。 当我运行我的应用程序时,使用AnnotationConfigApplicationContext - 一切正常。使用SpringJUnit4ClassRunner - 它没有。我想我在测试代码中遗漏了一些东西,但是我没有足够的知识去实现什么。 接口:
package bakery.intrface;
@FunctionalInterface
public interface Dessert {
void introduce();
}
蛋糕:
package bakery.desserts;
import bakery.intrface.Dessert;
import org.springframework.stereotype.Component;
@Component
public class Cake implements Dessert {
@Override
public void introduce() {
System.out.println("I am a cake!");
}
}
的Cookie:
package bakery.desserts;
import bakery.intrface.Dessert;
import org.springframework.stereotype.Component;
@Component
public class Cookie implements Dessert {
@Override
public void introduce() {
System.out.println("I'm a cookie!");
}
}
冰淇淋:
package bakery.desserts;
import bakery.intrface.Dessert;
import org.springframework.stereotype.Component;
@Component
public class IceCream implements Dessert {
@Override
public void introduce() {
System.out.println("I'm an ice cream!");
}
}
这个类,消耗一些bean,Taster:
package bakery;
import bakery.intrface.Dessert;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
@Component
public class Taster {
private Dessert dessert;
public void taste(){
dessert.introduce();
}
@Autowired
@Qualifier("iceCream")
public void setDessert(Dessert dessert) {
this.dessert = dessert;
}
}
配置:
package bakery.config;
import bakery.Bakery;
import bakery.Taster;
import bakery.desserts.Cake;
import bakery.intrface.Dessert;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
@ComponentScan(basePackageClasses = Bakery.class)
public class BakeryConfig {
}
运行课程:
package bakery;
import bakery.config.BakeryConfig;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Bakery {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(BakeryConfig.class);
String[] beans = context.getBeanDefinitionNames();
Taster taster = (Taster) context.getBean("taster");
taster.taste();
}
}
测试类:
package bakery;
import bakery.config.BakeryConfig;
import bakery.intrface.Dessert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import static org.junit.Assert.assertNotNull;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = BakeryConfig.class)
public class BakeryTest {
@Autowired
Dessert dessert;
@Autowired
Taster taster;
@Test
public void contextInit(){
assertNotNull(dessert);
dessert.introduce();
}
@Test
public void tasterInit(){
assertNotNull(taster);
}
}
当我运行测试时,我得到了异常:没有定义类型为[bakery.intrface.Dessert]的限定bean:期望的单个匹配bean但找到3:cookie,iceCream,cake。
答案 0 :(得分:2)
有3"甜点"在应用程序上下文中,您必须指定要连接的bean。
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = BakeryConfig.class)
public class BakeryTest {
@Autowired
@Qualifier("iceCream") // <===================== you must specify which bean to be wired
Dessert dessert;
@Autowired
Taster taster;
答案 1 :(得分:1)
这是可以预期的。
声明
@Autowired
Dessert dessert;
要求Dessert
个对象。 Dessert
是界面,有三个实施类Cookie
,IceCream
和Cake
。由于您还没有明确指出您想要的哪些实现,因此Spring会抛出错误,因为它无法决定该怎么做。
如果您在测试中需要此项,则可以执行以下操作之一:
@Autowired
@Qualifier("iceCream")
Dessert dessert;
只获得冰淇淋甜点,
OR
@Autowired
List<Dessert> desserts;
获取包含所有实现的列表。