3. DI
3.1 DI 的配置使用
1. 依赖和依赖注入
- 首先看看类之间的关系
- 泛华: 表示类和类, 接口和接口的继承关系
- 实现, 类对接口的实现
- 依赖: 类和类之间在方法中有使用关系
- 关联: 表示类与类或类与接口之间的依赖关系,表现为 “拥有关系”;
- 聚合: 属于是关联的特殊情况, 体现部分-整体, 整体和部分不同生命周期
- 组合: 属于关联的特殊情况, 整体和部分生命周期一致
- spring IOC容器包含: Bean依赖容器, Bean容器里的依赖资源
- 容器创建Bean并且管理Bean生命周期
- 容器注入Bean的依赖资源, 比如Bean, 文件, 常量数据
- 依赖注入的好处:
- 动态替换Bean依赖对象, 程序更加灵活
- 更好实践面向接口编程, Bean只需指定依赖对象的接口
- 更好实践对象组合, 而不是类继承
- 增加Bean的复用性, 降低Bean的耦合
2. 注入方式实践
Spring IOC 注入依赖资源主要是: 构造器注入, Setter注入, 方法注入
1. 构造器注入:
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<bean id="byIndex" class="cn.kuang.spring_example.di.service.impl.HelloApiImpl" >
<constructor-arg index="0" value="Hello World, DI By Index"/>
<constructor-arg index="1" value="1"/>
</bean>
<bean id="byType" class="cn.kuang.spring_example.di.service.impl.HelloApiImpl" >
<constructor-arg type="java.lang.String" value="Hello World, DI By Type"/>
<constructor-arg type="int" value="2"/>
</bean>
<bean id="byName" class="cn.kuang.spring_example.di.service.impl.HelloApiImpl" >
<constructor-arg name="message" value="Hello World, DI BY Name" />
<constructor-arg name="index" value="3" />
</bean>
</beans>
public class HelloApiImpl implements HelloApi {
private String message;
private int index;
public HelloApiImpl(String message, int index) {
this.message = message;
this.index = index;
}
@Override
public void sayHello() {
System.out.println(index + " : " + message);
}
}
public class TestDi {
BeanFactory factory = new ClassPathXmlApplicationContext("spring-di.xml");
HelloApiImpl hello;
@Test
public void test1(){
hello = (HelloApiImpl) factory.getBean("byIndex");
hello.sayHello();
}
@Test
public void test2(){
hello = (HelloApiImpl) factory.getBean("byType");
hello.sayHello();
}
@Test
public void test3(){
hello = (HelloApiImpl) factory.getBean("byName");
hello.sayHello();
}
}
2. Setter注入:


- Spring如何知道setter:
- Java Bean本质是pojo类, 有下面限制:
- 必须有公共无参构造器
- 属性为private, 提供set/get方法
- 在xml中添加 :
<bean id="setBean" class="cn.kuang.spring_example.di.service.impl.HelloApiImpl2" >
<property name="message" value="Hello World, DI BY SET" />
<property name="index" value="4" />
</bean>
public class HelloApiImpl2 implements HelloApi {
private String message;
private int index;
public void setMessage(String message) {
this.message = message;
}
public void setIndex(int index) {
this.index = index;
}
@Override
public void sayHello() {
System.out.println(index + " : " + message);
}
}
@Test
public void test3(){
hello = (HelloApiImpl) factory.getBean("byName");
hello.sayHello();
}
- Spring如何知道setter:
- Java Bean本质是pojo类, 有下面限制:
- 必须有公共无参构造器
- 属性为private, 提供set/get方法
3. 配置总结
一、构造器注入:
1)常量值
简写:<constructor-arg index="0"value=" 常量 "/>
全写:<constructor-arg index="0"><value> 常量 </value></constructor-arg>
2)引用
简写:<constructor-arg index="0"ref=" 引用 "/>
全写:<constructor-arg index="0"><ref bean=" 引用 "/></constructor-arg>
二、setter 注入:
1)常量值
简写:<property name="message"value=" 常量 "/>
全写:<property name="message"><value> 常量 </value></ property>
2)引用
简写:<property name="message"ref=" 引用 "/>
全写:<property name="message"><ref bean=" 引用 "/></ property>
3)数组:<array> 没有简写形式
4)列表:<list> 没有简写形式
5)集合:<set> 没有简写形式
6)字典
简写:<map>
<entry key=" 键常量 "value=" 值常量 "/>
<entry key-ref=" 键引用 "value-ref=" 值引用 "/>
</map>
全写:<map>
<entry><key><value> 键常量 </value></key><value> 值常量 </value></entry>
<entry><key><ref bean=" 键引用 "/></key><ref bean=" 值引用 "/></entry>
</map>
7)Properties:没有简写形式