Spring中@Primary注解使用。
假定,有如下两个类,OperaSinger and MetalSinger。
MetalSinger类
@Component
public class MetalSinger implements Singer {
@Override
public String sing(String lyrics) {
return "I am singing with DIO voice: "+lyrics;
}
}
OperaSinger类
public class OperaSinger implements Singer {
@Override
public String sing(String lyrics) {
return "I am singing in Bocelli voice: "+lyrics;
}
}
Singer接口
public interface Singer {
String sing(String lyrics);
}
现在定义SingerService并且注入Singer
SingerService类
@Component
public class SingerService {
private static final Logger logger = LoggerFactory.getLogger(SingerService.class);
@Autowired
private Singer singer;
public String sing(){
return singer.sing("song lyrics");
}
}
你觉得哪个Singer实现类会被注入?结果如下:
I am singing with DIO voice: song lyrics
这是因为OperaSinger类未定义@Component或者@Service注解,所以Spring对于OperaSinger类完全没想法,现在加上@Component注解:
@Component
public class OperaSinger implements Singer {
@Override
public String sing(String lyrics) {
return "I am singing in Bocelli voice: "+lyrics;
}
}
然后,会得到异常信息:
org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [main.service.Singer] is
defined: expected single matching bean but found 2: metalSinger,operaSinger
原因显而易见,如果有不止一个bean的相同类型,并且使用了@Autowired注解根据类型绑定bean,就会得到这个异常信息,Spring不知道如何去选择。 现在给OperaSinger类加上@Primary注解。
@Primary
@Component
public class OperaSinger implements Singer {
@Override
public String sing(String lyrics) {
return "I am singing in Bocelli voice: "+lyrics;
}
}
结果如下:
I am singing in Bocelli voice: song lyrics
这是因为OperaSinger类加上了@Primary注解,Primary主要的,从单词意思就可以理解。 另外解决方法是,使用@Qualifier注解使用value属性指定bean的名称。
@Component
public class SingerService {
private static final Logger logger = LoggerFactory.getLogger(SingerService.class);
@Autowired
@Qualifier(value = "operaSinger")
private Singer singer;
public String sing(){
return singer.sing("song lyrics");
}
}