DI依赖注入是核心机制,也是IOC的实现方式。
DI(Dependency Injection)——依赖注入,即给Bean注入属性值或其他Bean的引用(属性赋值)。
IOC容器在运行期间,动态地将某种依赖关系注入到对象之中。
传统的注入方式:
设值注入也称属性注入,是指IOC容器通过成员变量的setter方法来注入被依赖对象。
这种注入方式简单、直观,因而在Spring的依赖注入中大量使用。
下面案例将会对前面进行改写,使之更加规范。Spring推荐面向接口编程。不管是调用者,还是被依赖对象,都应该为之定义接口,而不是面向实现类编程,这样以便程序后期的升级、维护。
案例:
先定义Person接口,如下:
public interface Person{
//定义一个方法
public void useAxe();
}
定义Axe接口,如下:
public interface Axe{
//Axe接口中定义一个chop()方法
public String chop();
}
Spring推荐面向接口编程,这样可以更好地让规范和实现分离,从而提供更好的解耦。
对于一个JavaEE应用,不管是Dao组件,还是业务逻辑组件,都应该先定义一个接口,该接口定义了该组件应该实现的功能,但功能的实现则是由其实现类提供。
Person实现类:
public class Chinese implements Person{
private Axe axe;
//设置注入所需要的setter方法
Public void setAxe(Axe axe){
This.axe = axe;
}
//实现接口的chop()方法
public void useAxe(){
//调用axe的chop()方法
//表明Person对象依赖于Axe对象
System.out.println(axe.chop());
}
}
Axe的实现类:
public class StoneAxe implements Axe{
public String chop(){
return "一源星河";
}
}
applicationContext-Beans.xml
配置:
<bean id=”stoneAxe” class=”com.alibaba.service.impl.StoneAxe”>bean>
<bean id="chinese" class="com.alibaba.service.impl.Chinese">
<property name="axe" ref="stoneAxe">property>
bean>
构造注入,即通过类中的构造方法进行初始化。
构造注入是指在构造实例时,完成依赖关系的初始化。
默认使用无参构造方法。
问题:
答案: 使用
注:Bean中要有对应参数的构造方法。
类的定义:
package com.alibaba;
public class User{
private Integer uid;
private String uname;
//此处省略setter/getter方法
//默认使用的无参构造方法
public User(){
}
//全参构造方法
public User(Integer uid, String uname){
this.uid = uid;
this.uname = uname;
}
}
applicationContext-beans.xml
配置:
<bean id="user" class="com.alibaba.User">
<constructor-arg value="3">constructor-arg>
<constructor-arg value="一源星河">constructor-arg>
bean>
当某一个类中的成员变量是一个对象时,需要为该成员变量注入一个对象。如下:
public class User{
//成员变量是一个对象
private UserDao userDao;
//成员变量的setter/getter方法(如省略会如何?)
public void setUserDao(UserDao userDao){
this.userDao = userDao;
}
public UserDao getUserDao(){
return this.userDao;
}
}
applicationContext-beans.xml
配置:
<bean id="userDao" class="com.alibaba.UserDao">bean>
<bean id="user" class="com.alibaba.User">
<property name="userDao" ref="userDao">property>
bean>
类的定义:
public class User{
//List集合对象
private List<String> strList;
private List<Cat> catList;
//Set集合对象
private Set<String> strSet;
//Map集合对象
private Map<String,String> strMap;
//封装setter/getter方法
public void setStrList(List<String> strList){
this.strList = strList;
}
public StrList getStrList(){
return this.strList;
}
public void setStrSet(Set<String> strSet){
this.strSet = strSet;
}
public StrSet getStrSet(){
return this.strSet;
}
public void setStrMap(Map<String,String> strMap){
this.strMap = strMapt;
}
public StrMap getStrMap(){
return this.strMap;
}
}
List集合注入:
<bean id="user" class="com.alibaba.User">
……
<property name="strlist">
<list>
<value>王者荣耀1value>
<value>王者荣耀2value>
list>
property>
<property name="catList">
<list>
<ref bean="cat1"/>
<ref bean="cat2"/>
list>
property>
bean>
<bean id=”cat1” class=”com.alibaba.Cat” scope=”prototype” />
<bean id=”cat2” class=”com.alibaba.Cat” scope=”prototype” />
Set集合注入:
<bean id="user" class="com.alibaba.User">
……
<property name="strSet">
<set>
<value>王者荣耀1value>
<value>王者荣耀2value>
set>
property>
bean>
Map集合注入:
<bean id="user" class="com.alibaba.model.User">
……
<property name="strMap">
<map>
<entry key="aa" value="小王">entry>
<entry key="bb" value="小李">entry>
<entry key="cc" value="小强">entry>
map>
property>
bean>