Spring IOC的核心机制:实例化与注入 (2)

这个时候控制就没有那条打印语句的输出内容了,此时我们通过浏览器来访问BannerController的路由,此时就会在控制台输出构造方法里打印语句的输出内容了。

对象的注入逻辑

上文 Diana的就是一个单独的类,没有实现任何接口,这种实现方式他是有问题的,很难进行扩展,这里不应该一类具体的实现类,而是要应该依赖抽象,这样才能满足开闭原则,让程序具有良好的扩展性。

这里让 Diana实现了一 Skill接口,

public interface Skill { void q(); void w(); void e(); void r(); }

在BannerController注入这里也要改一下:

@Autowired private Skill diana;

运行程序,发先能够运行成功,如果新添加一个英雄的实现类:

@Component public class Irelia implements Skill { public Irelia() { System.out.println("Hello, Irelia"); } public void q(){ System.out.println("Irelia Q"); } public void w(){ System.out.println("Irelia W"); } public void e(){ System.out.println("Irelia E"); } public void r(){ System.out.println("Irelia R"); } }

我们再去运行程序,发现还是能运行成功,并且发现注入的是 Diana而不是 Irelia,那这里我们可能会问为什么呀,前面好像也没指定注入哪个实现类。

难道是因为 private Skill diana;这里写了 diana么?你还别说,还真是这个原因,这里涉及到spring的注入机制了。

当spring的IOC容器注入bean的时候,如果发现有多个相同类型的bean时,就会去看它们的名称(name),如果名称符合要求,就会注入这个名称的bean。每个被容器扫描到的bean都会有一个默认的name,就是它的类名,首字母会小写,比如我们实例中的:BannerController的name就是bannerController,Irelia就是irelia。

可以试着把 private Skill diana改成 private Skill skill,再次运行,就会发生报错:

file

提示你找不到响应的bean。这里要明确一点哈,虽然报错了,但是这种写法是标准的,上面那个直接写实现类的名字不是标准的写法。

那怎么解决这个找不到的问题呢?

spring提供了一个@Qualifier的注解,给他传入要注入bean的名字,就可以指定注入的bean,@Qualifier("irelia")。

总结

Autowired的注入方式有两种,一种是按照类型注入,一种是按照名称注入,默认是按照类型注入,如果只有一个实现类 Diana,这里写成 private Skill skill,运行程序,你会发现是能够注入成功的。因为Skill类型下只有一个实现类,自然就是注入它了。如果有多个实现类,那就会先按照这个类型查找,这个类型下所有到的实现类再按照名称查找,直至找到符合要求的,找不到就报错。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zywwyy.html