Spring DI依赖注入
DI(Dependency Injection)依赖注入 。
依赖注入,即组件之间的依赖关系由容器在应用系统运行期来决定,也就是由容器动态地将某种依赖关系的目标对象实例注入到应用系统中的各个关联的组件之中。
简单来说,所谓的依赖注入其实就是,在创建对象的同时或之后,如何给对象的属性赋值。
如果对象由我们自己创建,这一切都变得很简单,例如:
User user = new User();
user.setName("韩少云");
user.setAge(18);
或者:
User user = new User("韩少云", 18);
如果对象由spring创建,那么spring是怎么给属性赋值的?spring提供两种方式为属性赋值:
- Set方式注入
- 构造方法注入
当然也可以使用bean标签中使用autowrit属性进行自动注入 autowire属性
set方法注入
即调用Bean的set方法进行注入
property标签
property标签在bean标签内部使用, 用于调用set方法注入属性的值
name属性
name就是需要注入的属性名, 实际上name是set方法的名字, 如果调用setName()方法, 那么name的值就是方法名去掉set后首字母小写, 一般和属性名相同
value属性
value属性是给属性赋的值, 一般给基本类型及其对应的包装类型或String类型赋值时可以使用value, 如果需要赋值的时一个对象(引用类型), 那么应该使用ref进行赋值, 就不能使用value了
ref属性
ref属性是给对象(引用类型)赋值的时候才会使用的属性
set注入案例
例如我们有一个User类
public class User {
private int id;
private String name;
private Integer age;
// Bean类
private UserInfo info;
// getter, setter, toString, 有参无参构造
}
将对象存入IOC容器的时候我们可以这样进行初始化赋值: applicationContext.xml进行如下配置
<bean id="user" class="com.test.pojo.User">
<!-- 通过set方式为普通属性赋值 -->
<property name="id" value="1"></property>
<property name="name" value="张三"></property>
<property name="age" value="22"/>
<!-- 如果属性是个Bean, 则使用ref属性, 属性值是对应Bean的id值 -->
<property name="info" value="userInfo"/>
</bean>
<bean id="userInfo" class="com.test.pojo.UserInfo"/>
这样我们从spring的IOC容器中获取到User对象后, 里面的属性就自动进行了赋值.
构造方法注入
即调用Bea的构造方法进行依赖注入, 给对象的属性赋值
constructor-arge标签
constructor-arge标签和property标签一样, 也是在bean标签内使用, constructor-arge标签进行依赖注入是调用的构造方法
index属性
构造方法里的参数索引(按顺序, index从0开始), 表示构造方法的第一个参数
name属性
匹配构造方法的属性名进行依赖注入
value属性
value属性和property中的value属性一样, 一般给基本类型及其对应的包装类型或String类型赋值时可以使用value
ref属性
同property中的ref属性是给对象(引用类型)赋值的时候才会使用的属性
案例
例如上面的set方法注入
我们可以修改xml配置文件为:
<bean id="user" class="com.tedu.pojo.User" scope="prototype">
<constructor-arg index="0" value="张三"/>
<constructor-arg index="1" value="45"/>
<constructor-arg index="2" ref="userInfo"/>
<!-- 也可以使用构造方法的参数名进行依赖注入
<constructor-arg name="name" value="张三"/>
<constructor-arg name="age" value="45"/>
<constructor-arg name="info" ref="userInfo"/>
-->
</bean>
<bean id="userInfo" class="com.tedu.pojo.UserInfo"></bean>
同样实现了依赖的注入
集合类型的注入
例如我们的list, set, map集合等注入, 也是使用property标签进行注入, 即调用对应的set方法
List集合注入
<property name="like">
<list>
<value>元素1</value>
<value>元素2</value>
<ref>引用元素1</ref>
<ref>引用元素2</ref>
</list>
</property>
Set集合注入
<property name="city">
<set>
<value>元素1</value>
<value>元素2</value>
<ref>引用类型1</ref>
<ref>引用类型2</ref>
</set>
</property>
Map集合注入
<property name="map">
<map>
<entry key="key1" value="元素1"/>
<entry key="key2" value="元素2"/>
<entry key="key2" ref="引用类型1"/>
<entry key="key2" ref="引用类型2"/>
</map>
</property>
Properties对象注入
值只能是字符串, 不能是引用类型
<property name="prop">
<props>
<prop key="driverClassName">com.mysql.jdbc.Driver</prop>
<prop key="url">jdbc:mysql//localhost:3306/db</prop>
<prop key="username">root</prop>
<prop key="password">123</prop>
</props>
</property>
案例
ValueBean类
public class ValueBean {
private String name;
private Integer age;
private List<String> like;
private Set<String> city;
private Map<String, Object> map;
private Properties prop;
// getter, setter, toString, 有参无参构造
}
applicationContext.xml
<bean id="valueBean" class="cn.tedu.demo.ValueBean">
<property name="name" value="自拍狂"/>
<property name="age" value="20"/>
<property name="like">
<list>
<value>路由</value>
<value>上天</value>
<value>青青草原捉羊</value>
<value>听缪贼</value>
</list>
</property>
<property name="city">
<set>
<value>石家庄</value>
<value>廊坊</value>
<value>山沟子</value>
</set>
</property>
<property name="map">
<map>
<entry key="name" value="名字1"/>
<entry key="age" value="18"/>
</map>
</property>
<property name="prop">
<props>
<prop key="driverClassName">com.mysql.jdbc.Driver</prop>
<prop key="url">jdbc:mysql//localhost:3306/db</prop>
<prop key="username">root</prop>
<prop key="password">123</prop>
</props>
</property>
</bean>
当然, 进行依赖注入的时候也可以分开写
例如对list集合进行依赖注入的时候
<bean id="valueBean2" class="cn.tedu.demo.ValueBean">
<property name="like" ref="listLike"></property>
</bean>
<util:list id="listLike">
<value>1111</value>
<value>2222</value>
</util:list>