DI三种注入方式
DI是IOC的另一种理解方式,但更注重体现在注入
1.set注入:通过set方法注入(所以要求类提供set方法)
2.构造器注入:通过调用有参构造器创建对象(所以要求提供有参构造方法)
spring的ioc注入方式有几种
一、Set注入
二、构造器注入
三、静态工厂的方法注入
内容拓展:
一、Set注入
1、这是最简单的注入方式,假设有一个SpringAction,类中需要实例化一个SpringDao对象,那么就可以定义一个private的SpringDao成员变量,然后创建SpringDao的set方法(这是ioc的注入入口)。
2、随后编写spring的xml文件,bean中的name属性是class属性的一个别名,class属性指类的全名,因为在SpringAction中有一个公共属性Springdao,所以要在bean标签中创建一个property标签指定SpringDao。property标签中的name就是SpringAction类中的SpringDao属性名,ref指下面bean name="springDao"...,这样其实是spring将SpringDaoImpl对象实例化并且调用SpringAction的setSpringDao方法将SpringDao注入。
二、构造器注入
1、这种方式的注入是指带有参数的构造函数注入,看下面的例子,我创建了两个成员变量SpringDao和User,但是并未设置对象的set方法,所以就不能支持第一种注入方式,这里的注入方式是在SpringAction的构造函数中注入,也就是说在创建SpringAction对象时要将SpringDao和User两个参数值传进来。
2、在XML文件中同样不用property的形式,而是使用constructor-arg标签,ref属性同样指向其它bean标签的name属性。
三、静态工厂的方法注入
1、静态工厂顾名思义,就是通过调用静态工厂的方法来获取自己需要的对象,为了让spring管理所有对象,我们不能直接通过"工程类.静态方法()"来获取对象,而是依然通过spring注入的形式获取。
2、同样看关键类,这里我需要注入一个FactoryDao对象,这里看起来跟第一种注入一模一样,但是看随后的xml会发现有很大差别。
常见的三种注解注入方式对比
java
field 注入方式是使用最多的,原因是这种方式使用起来非常简单,代码更加简洁。
java
在 Spring 3.x 刚推出的时候,Spring 官方在对比构造器注入和 Setter 注入时,推荐使用 Setter 方法注入:
Spring 3.x Constructor-based or setter-based DI?
意思是说,当出现很多注入项的时候,构造器参数可能会变得臃肿,特别是当参数时可选的时候。Setter 方式注入可以让类在之后重新配置和重新注入;
java
Spring 4.x 的时候,Spring 官方在对比构造器注入和 Setter 注入时,推荐使用构造器注入方式:
Spring 4.x Constructor-based or setter-based DI?
因为使用构造器注入方式注入的组件 不可变 ,且保证了需要的依赖 不为 null 。此外,构造器注入的组件总是能够在 完全初始化的状态 返回给客户端(调用方);对于很多参数的构造器说明可能包含了太多了职责,违背了单一职责原则,表示代码应该重构来分离职责到合适的地方。
在对比 Setter 方法注入和 构造器注入的时候 分别引用的 Spring 官方文档的第二段阐述了除推荐方式的另一种方式的特点。
在 Spring 3.x 的时候 Spring 推荐 Setter 方法注入,第二段表示:一些纯粹主义者喜欢基于构造函数的注入。提供所有对象依赖项意味着对象总是在完全初始化状态下返回给客户机(调用)代码。缺点是对象不太容易重新配置和重新注入。
在 Spring 4.x 的时候 Spring 推荐构造器注入,第二段表示:Setter 注入应该主要用于可选的依赖项,这些依赖项可以在类中分配合理的默认值。否则,必须在代码使用依赖项的任何地方执行非空检查。setter 注入的一个好处是,setter 方法使该类的对象能够在以后重新配置或重新注入。
Setter 注入 应该被用于可选依赖项。当没有提供它们时,类应该能够正常工作。在对象被实例化之后,依赖项可以在任何时候被更改。
构造器注入 有利于强制依赖。通过在构造函数中提供依赖,您可以确保依赖对象在被构造时已准备好被使用。在构造函数中赋值的字段也可以是final的,这使得对象是完全不可变的,或者至少可以保护其必需的字段。
构造器注入还可以避免 Field 注入 的循环依赖问题,比如 在 Alpha 中注入 Beta,又在 Beta 中注入 Alpha。如果使用构造器注入,在 Spring 启动的时候就会抛出 BeanCurrentlyInCreationException 提醒循环依赖。
参考:
spring注入bean的几种方式
依赖注入方式有三种:
①使用构造函数注入:使用标签constructor-arg/
②使用set方法注入:使用标签property/
③使用注解的方式注入:常用注解@Autowrite