spring依赖注入DI
Spring的依赖注入是一种将组件间依赖关系的创建和管理独立与程序以外的技术,举例说来,类A依赖于类B,通常的做法是先new 一个A对象,让后new 一个B对象,通过调用的方法将B对象注入,但是DI提供的机制可以将这种对象依赖关系的创建配置到文件中,让框架自动创建维护这个关系,而业务系统只需要关心自身业务
核心思想
java bean可以简单理解成那些只有简单的get,set方法的java类(还有其他方法),spring DI中管理的bean推荐这种形式,而面向接口编程也是spring推荐的方式,优势很显然--容易解耦,当需要替换新的实现类时只需要指向不同的实现就可以,但是上层的调用逻辑只对接口操作
优势
1.减少复制粘贴代码
--它可以将创建依赖组建的繁琐代码中解脱出来,交给框架去做吧!
2.依赖配置化
--依赖关系都是定义在配置文件中,依赖关系简洁明了,修改依赖关系不需要重新编译,重新部署即可运行
3.在统一的地方管理依赖
--所有的依赖都定义在统一的配置文件中
4.提高可测试性
--可以修改DI依赖,指向mock的组件来大大简化测试过程
5.鼓励良好的设计
--spring提倡面向接口编程,应用程序各个组件之间通过接口调用,这样当替换不同的实现类时只需要更新配置不同的实现,而上层的调用不需要作任何改动
注入类型
1.构造器注入
举个例子
package com.crazycoder2010.spring.ioc; public class ConstructorInjection { private String stringValue; private int intValue; public ConstructorInjection(String stringValue) { this.stringValue = stringValue; } public ConstructorInjection(int intValue, String stringValue) { this.stringValue = stringValue; this.intValue = intValue; } public void printMessage() { System.out.println("{stringValue:" + this.stringValue + ",intValue:" + this.intValue + "}"); } }
有这样一个简单的类,要通过构造器方式注入两个属性值,看看我们在spring文件中该如何配置,看这个小例子有两个构造函数,一个只有一个参数,另一个构造函数有两个参数,分别来注入一下
<bean id="constructor1" class="com.crazycoder2010.spring.ioc.ConstructorInjection"> <constructor-arg type="java.lang.String"> <value>Hello</value><!-- 这里定义了要注入的字符串,只有一个参数,因此只能调用单个参数的构造函数 --> </constructor-arg> </bean> <!-- 注入两个参数的构造函数 --> <bean id="constructor2" class="com.crazycoder2010.spring.ioc.ConstructorInjection"> <constructor-arg type="int" index="0"><--推荐写好构造函数的参数类型,index(注意是从0开始而不是从1开始),这样避免有些构造函数参数类型相似导致构造出来的对象与实际想创建的不是同一个函数的问题 --> <value>100</value> </constructor-arg> <constructor-arg type="java.lang.String" index="1"> <value>你好</value> </constructor-arg> </bean>
<bean id="constructor1" class="com.crazycoder2010.spring.ioc.ConstructorInjection"> <constructor-arg type="java.lang.String"> <value>Hello</value><!-- 这里定义了要注入的字符串,只有一个参数,因此只能调用单个参数的构造函数 --> </constructor-arg> </bean>
调用一下
IocTest test = new IocTest(); ConstructorInjection c1 = (ConstructorInjection)test.getBean("constructor1"); c1.printMessage(); ConstructorInjection c2 =(ConstructorInjection)test.getBean("constructor2"); c2.printMessage();
打印输出--证明配置已经生效
{stringValue:Hello,intValue:0}
{stringValue:你好,intValue:100}
2.gettter,setter注入
一个简单的类,我们对要打印的message进行注入
package com.crazycoder2010.spring.ioc; public class SetterInjection { private String message; public void setMessage(String message) { this.message = message; } public void printMessage(){ System.out.println(this.message); } }
xml配置
<bean id="setterInjection" class="com.crazycoder2010.spring.ioc.SetterInjection"> <property name="message"> <!--这个地方name与SetterInjection类中的成员变量private String message名字保持完全一直,java bean规范 --> <value>Hello,world!</value> </property> </bean>
看下打印输出
Hello,world!