今天,我想起了我的一个老朋友(@primary),我们从教程到教程都遇到了他。 您知道在Spring @Autowired批注中按类型工作,也就是说,如果Spring找到符合类型的匹配的合格bean,则会将其注入。让我们在示例中进行查看。
假设我有两个歌手班; OperaSinger和MetalSinger。
@Component
public class MetalSinger implements Singer{@Overridepublic String sing(String lyrics) {return "I am singing with DIO voice: "+lyrics;}
}
public class OperaSinger implements Singer {@Overridepublic String sing(String lyrics) {return "I am singing in Bocelli voice: "+lyrics;}
}
它们都实现了Singer接口。
public interface Singer {String sing(String lyrics);
}
并定义一个SingerService并将Singer bean注入其中。
@Component
public class SingerService {private static final Logger logger = LoggerFactory.getLogger(SingerService.class);@Autowiredprivate Singer singer;public String sing(){return singer.sing("song lyrics");}
}
你怎么看; 哪个歌手会被注入里面? 结果如下:
我用DIO声音唱歌:歌词。
这是因为OperaSinger并未定义为Component或Service,因此Spring没有任何线索。 如果我们向其添加@Component注释:
@Component
public class OperaSinger implements Singer {@Overridepublic String sing(String lyrics) {return "I am singing in Bocelli voice: "+lyrics;}
}
比我将得到此异常:
org.springframework.beans.factory.NoUniqueBeanDefinitionException:没有定义类型为[main.service.Singer]的合格bean:期望的单个匹配bean,但找到2:metalSinger,operaSinger
原因很明显。 如果我有多个具有相同类型的bean,并且使用绑定类型的@Autowired注释,则将出现此异常。 Spring并不知道应该使用哪个Singer。
让我们喜欢一种音乐类型,并告诉Spring使用OperaSinger作为Primary。
@Primary
@Component
public class OperaSinger implements Singer{@Overridepublic String sing(String lyrics) {return "I am singing in Bocelli voice: "+lyrics;}
}
如果我们进行SingerService调用,则会得到:
"I am singing in Bocelli voice: song lyrics"
那是因为我们选择OperaSinger作为主要对象,这意味着“如果您对类型感到困惑,最好使用此类型”。 另一种方法是使用限定符名称,将名称直接映射到bean。
翻译自: https://www.javacodegeeks.com/2015/04/spring-annotations-i-never-had-the-chance-to-use-part-1-primary.html