DI(依赖注入,Dependency Injection)

DI(依赖注入,Dependency Injection)

一、概念
简单理解为给予成员变量进行赋值的过程
举个例子:A -> B -> C,A依赖于B,B依赖于C
  • 使用Spring前:C c = new C();B b = new B( c );A a = new A( b )
  • 使用Spring后:容器创建A,A依赖B再去创建B,B依赖C再去创建C
发现使用Spring后,思路相对使用前是反的,所以也定义为控制反转
二、注入方式
1、构造器注入
  • 需要类中拥有有参构造函数,通过有参构造函数进行注入
  • xml里在bean中<constructor-arg />标签进行注入
2、setter注入
  • 需要类中拥有setter方法,通过setter方法进行注入
  • xml里在bean中<property />标签进行注入

问题:如何选择这两种方式?

Spring官方说明: 
	由于您可以混合使用基于构造函数和基于setter的DI,一般情况下,我们对于【强制性依赖项】使用构造函数,对于【可选依赖项】使用setter方法注入,这是一个很好的经验法则。 注意,在setter方法上使用【@Required】注解可以使属性成为必需依赖项。
​ 	Spring团队通常提倡构造函数注入,因为它允许你将应用程序组件实现为不可变的对象,并确保所需的依赖项不是”空“的。 而且,构造函数注入的组件总是以完全初始化的状态返回给客户端(调用)代码。
​ 	Setter注入主要应该只用于可选依赖项,这些依赖项可以在类中分配合理的默认值。 setter注入的一个好处是,setter方法使该类的对象能够在稍后进行重新配置或重新注入。
​ 有时,在处理您没有源代码的第三方类时,您可以自行选择。 例如,如果第三方类不公开任何setter方法,那么构造函数注入可能是DI的唯一可用形式。

3、直接值注入(原语、字符串等)
  • 字符串,int之类的使用<property name="" value=""/>标签
  • list使用<list> <value> value </value> ... </list>标签
  • map使用<map> <entry key="" value=""/> </map>标签
  • 数组使用<array> <value> value </value> </array>标签
  • null值使用<property name=""> <null/> </property>标签
三、命名空间
上面写到的构造器注入和setter方法注入的两种方式可以使用命名空间,简化代码编写
  • 构造器需要引入xmlns:c="http://www.springframework.org/schema/c"
  • setter需要引入xmlns:p="http://www.springframework.org/schema/p"
四、循环依赖

问题说明

  • A依赖B,B又依赖A,如何解决这种问题
  • Spring提供三级缓存解决,但二级缓存也可以解决

个人理解思路
当创建A时,发现依赖B,去一、二级缓存查找B未找到,则先创建A的半成品放入二级缓存;再去创建B,又发现B依赖A,去一、二级缓存查找A,拿到A给予B,将成品B放入一级缓存,再将B给予A等到成品A。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值