最近由于希望使用Spring在XML文件中定义List的bean,并使用@Autowired进行注入到对象中使用,遇到到一些坑,记录一下作为备忘。
@Autowired
@Autowired是Spring定义的注解,是根据类型进行自动装配的。如果当spring上下文中存在不止一个存在一个需要装配类型的bean时,就会抛出BeanCreationException异常;这时我们可以使用@Qualifier配合@Autowired来解决问题。
@Resource
@Resource是JSR-250规定的注解,主要有两种类型的属性type及name,所以如果使用name属性,则使用byName的自动注入策略,而使用type属性时则使用byType自动注入策略如果既不指定name也不指定type属性,这时将通过反射机制使用byName自动注入策略 。
@Resource装配顺序:
- 如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常
- 如果指定了name,则从上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常
- 如果指定了type,则从上下文中找到类型匹配的唯一bean进行装配,找不到或者找到多个,都会抛出异常
- 如果既没有指定name,又没有指定type,则自动按照byName方式进行装配;如果没有匹配,则回退为一个原始类型进行匹配,如果匹配则自动装配;
使用区别
使用Spring注入List的时候在XML中定义:
1 | <util:list id="myList"> |
之后使用注解注入,代码1为:
1 |
|
注入失败。修改,代码2为:
1 |
|
注入仍然失败。修改,代码3为:
1 |
|
仍然失败。主要原因在于,使用Autowired注入,Spring默认使用按类型方式注入,而对于List集合类型Spring会读取其中的泛型类型进行注入,上面代码2的含义为注入当前bean中类型为String的对象,代码3的含义为注入当前bean中类型为String且qualifier是myList的对象。这两种含义都不能完成正确的注入。
正确使用
使用@Resource注入,引用stackoverflow上的解答使用正确方式为:
1 |
|
或者
1 |
|
因为Resource设置了name属性,Spring直接寻找id为myList的对象进行注入,可以注入成功。