构造函数注入 | setter注入 |
没有部分注入 | 有部分注入 |
不会覆盖setter属性 | 会覆盖setter属性 |
任意修改都会创建一个新实例 | 任意修改不会创建一个新实例 |
适用于设置很多属性 | 适用于设置少量属性 |
依赖注入的本质就是装配,装配是依赖注入的具体行为。
装配:创建应用对象之间协作关系的行为。也就是说,当一个对象的属性是另一个对象时,实例化时就需要为这个对象属性进行实例化。
用xml装配bean是一件很繁琐的事情,而且还需要找到对应类型的bean才能装配。
如果一个对象只通过接口来表明依赖关系,那么这种依赖就能在对象本身毫不知情的情况下,用不同的具体实现进行切换。但这样会有一个问题:在传统的依赖注入配置中,我们必须要明确给属性装配哪一个bean的引用,一旦bean很多,就不好维护了。
基于这种问题,spring使用注解来进行自动装配,解决这个问题。自动装配就是开发人员不必知道具体要装配哪个bean的引用,这个识别的工作会由spring来完成。与自动装配配合的还有“自动检测”,这 个动作会自动识别哪些类需要被配置成bean,进而来进行装配。
这样就明白了,自动装配是为了将依赖注入“自动化”的一个简化配置的操作。
装配分为四种:byName, byType, constructor, autodetect。
(1)byName就是会将与属性的名字一样的bean进行装配。
(2)byType就是将同属性一样类型的bean进行装配。
(3)constructor就是通过构造器来将类型与参数相同的bean进行装配。
(4)autodetect是constructor与byType的组合,会先进行constructor,如果不成功,再进行byType。具体选择哪一种装配方式,需要配置
上面最常用的还是byName和byType。
自动装配时,装配的bean必须是唯一与属性进行吻合的,不能多也不能少,有且只有一个可以进行装配的bean,才能自动装配成功。否则会抛出异常。
如果要统一所有bean的自动装配类型,可以在
以上是通过xml配置的方式实现自动装配的,spring2.5之后提供了注解方式的自动装配。但是要使用这些注解,需要在配置文件
中配置
常用的自动装配注解有以下几种:@Autowired,@Resource,@Inject,@Qualifier,@Named。
(1)@Autowired注解是byType类型的,这个注解可以用在属性上面,setter方面上面以及构造器上面。
使用这个注解时,就不需要在类中为属性添加setter方法了。但是这个属性是强制性的,也就是说必须得装配上,如果没有找到合适的bean能够装配上,就会抛出异常。这时可以使用required=false来允许可以不被装配上,默认值为true。当required=true时,@Autowired要求必须装配,但是在没有bean能装配上时,就会抛出异常:NoSuchBeanDefinitionException,如果required=false时,则不会抛出异常。另一种情况是同时有多个bean是一个类型的,也会抛出这个异常。此时需要进一步明确要装配哪一个Bean,这时可以组合使用@Qualifier注解,值为Bean的名字即可。
注意:@Autowired注解是spring提供的,所以会依赖spring的包。
(2)@Qualifier注解使用byName进行装配,这样可以在多个类型一样的bean中,明确使用哪一个名字的bean来进行装配。
@Qualifier注解起到了缩小自动装配候选bean的范围的作用。
(3)@Injec注解是tbyType类型的,与@Autowired注解作用一样,而且是java ee提供的,完全可以代替@Autowired注解。
但是@Inject必须是强制装配的,没有required属性,也就是不能为null,如果不存在匹配的bean,会抛出异常。@Autowired与@Qualifier可以组合使用,@Inject也有一个组合的注解,就是@Named注解,与@Qualifier作用一样,也是byName,但是不是spring的,是java ee标准的。
这样就出现了两套自动装配的注解组合,@Autowired与@Qualifier是spring提供的,@Inject与@Named是java ee的。但是@Qualifier注解在java ee中也有一样,作用与spring的@Qualifier注解一模一样,只是所在的包不一样。不过建议大家使用spring的。
(4)@Resouce注解, 这个注解也是java ee的,也是byName类型的,原理同@Qualifier和@Named是一样的。
自动检测配置,也是springmvc中最牛的一项功能。只要一个配置
如果你想细化包被扫描的范围,可以使用