一般的方式需要配置bean或ref引用bean,自动注入会自动进行匹配,如果存在则创建。
匹配原则:使用Bean的id属性中的值去和相对应的值匹配
关键词autowire=""
default:默认
byType:根据类型自动匹配
byName:根据名字自动匹配
constructor: 根据构造器匹配
根据类型匹配
比如在person中使用byType并注入了Wife的bean标签:
在Person类中是有Wife这个类型的属性:
已知ioc容器中的存在Wife类型的bean,那么就会自动将Wife这个bean注入到Persong的属性中
测试方法:
/**
* 自动注入
*/
@Test
public void fun5(){
System.out.println("begin!");
Person person = app.getBean("person", Person.class);
System.out.println(person);
}
输出结果:
Wife加载
begin!
Person{id=null, name='null', gender='null', birth=null, ls=null, course=null, wife=Wife{id=null, name='妻子', gender='null', birth=null, ls=null, course=null}}
从结果可以发现注入Person中的Wife类型的bean就是我们配置的Wife类型的bean。
但是使用这个方式有一个问题:
当我们创建两个相同Wife类型的bean时就会 报错。
根据名字匹配
此时我将byType改为byName,然后注入两个Wife类型的bean -- wife 和 wife1:
那么这个时候就会自动去匹配Person类中set()方法的值与哪一个Wife类型Bean的id相同,
可以发现Person中setWife()方法与id="wife"的匹配,而不是与id="wife1"匹配,所以会将id="wife"的bean注入Person的wife属性中。
运行上面的测试代码:
Wife加载
Wife加载
begin!
Person{id=null, name='null', gender='null', birth=null, ls=null, course=null, wife=Wife{id=null, name='前妻', gender='null', birth=null, ls=null, course=null}}
结果也确实是与set()方法匹配的那个Wife类型的Bean被注入。
这里加载两次是因为配置了两个不同的Wife类型的Bean。
如果将set()方法改为:
查看结果:
begin!
Person{id=null, name='null', gender='null', birth=null, ls=null, course=null, wife=Wife{id=null, name='妻子', gender='null', birth=null, ls=null, course=null}}
被注入的是与wife1匹配的bean。
根据构造器匹配
此时进行匹配需要构造函数中的参数只有ioc容器中注入的参数,例如ioc容器中只注入了Wife的Bean,那么构造函数只能有Wife类型的参数,如果有其它参数那么将无法匹配。
此时将Person类中加入一个只有Wife参数的构造函数
这个方式会优先根据名字进行匹配:
比如下面:
参数为wife时输出结果:
参数为wife1时输出结果:
这和我们的配置的是一样的:
如果名字没有找到,那么就会根据类型进行匹配:
前面已知根据类型匹配只能注入一个Wife类型的bean,这里如果存在多个相同的Bean,那么会注入失败但是不会报错:
在xml中并没有配置wife2这个bean:
此时的输出结果为:
结果注入的是id="wife"的bean。
如果在自动注入的时候有两个相同的Bean参与匹配,那么可以使用primary="true",表示该Bean为主要Bean,如果primary="false",表示不参与自动注入。
输出结果:
存在相同的Bean也可以注入,并且为设置了优先的Bean,前面的byType也可以通过这个方式进行配置。