一、概念
- IoC,控制反转,是Spring核心思想之一。其主要内容是把对象的控制权从代码本身转移到外部容器中。即外部容器来管理对象的创建、初始化和销毁等操作。从而实现对象的松耦合,方便代码的开发和测试。
- DI,依赖注入,是对IoC思想的实现。在程序运行过程中,若需要调用另一个对象协助时,无须在代码中创建被调用者,而是依赖于外部容器,由外部容器创建后传递给程序。
- 所谓注入,可以简单理解为为对象的属性赋值,通常可以通过XML方式实现和通过注解方式实现。
二、基于XML实现DI之设值注入
设值注入,其实就是调用对象的setXX()方法,对其属性进行赋值。实现的基础是该对象为相应属性添加了set方法。
- 新建工程
直接复制上文的Demo工程,重命名为SpringDemo_DI
- 新建Person类,为其添加常用类型属性,并添加set/get方法和toString方法
package cn.cdy.springDemo.pojo;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class Person {
private String name;
private int age;
private Cat myCat;
private int[] myArray;
private List<String> myList;
private Set<Cat> mySet;
private Map<String,String> myMap;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Cat getMyCat() {
return myCat;
}
public void setMyCat(Cat myCat) {
this.myCat = myCat;
}
public int[] getMyArray() {
return myArray;
}
public void setMyArray(int[] myArray) {
this.myArray = myArray;
}
public List<String> getMyList() {
return myList;
}
public void setMyList(List<String> myList) {
this.myList = myList;
}
public Set<Cat> getMySet() {
return mySet;
}
public void setMySet(Set<Cat> mySet) {
this.mySet = mySet;
}
public Map<String, String> getMyMap() {
return myMap;
}
public void setMyMap(Map<String, String> myMap) {
this.myMap = myMap;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + ", myCat=" + myCat + ", myArray=" + Arrays.toString(myArray)
+ ", myList=" + myList + ", mySet=" + mySet + ", myMap=" + myMap + "]";
}
}
- 修改applicationContext.xml实现设值注入
<?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"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<bean id="cat" class="cn.cdy.springDemo.pojo.Cat">
<property name="name" value="lili"></property>
</bean>
<bean id="cat2" class="cn.cdy.springDemo.pojo.Cat">
<property name="name" value="mimi"></property>
</bean>
<bean id="person" class="cn.cdy.springDemo.pojo.Person">
<property name="name" value="小明"></property>
<property name="age" value="18"></property>
<property name="myCat" ref="cat"></property>
<property name="myArray">
<array>
<value>1</value><!-- 注意,value标签里面不用写双引号 -->
<value>2</value>
<value>3</value>
</array>
</property>
<property name="myList">
<list>
<value>西瓜</value>
<value>苹果</value>
</list>
</property>
<property name="mySet">
<set>
<ref bean="cat"/>
<ref bean="cat2"/>
</set>
</property>
<property name="myMap">
<map>
<entry key="qq" value="1234"></entry>
<entry key="weixin" value="4321"></entry>
</map>
</property>
</bean>
</beans>
- 在启动类中获取对象,并打印
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
Person p = ac.getBean(Person.class);
System.out.println(p);
}
- 运行
可以发现,打印结果中,Person对象的属性已经有值了。这就是设值注入的作用。
三、基于XML实现DI之构造注入
在实际开发中,还可以通过构造方法的方式,一次性为对象赋值。同样DI中也可以通过构造方法为对象赋值。
- 为Person类添加构造方法
public Person() {
super();
}
public Person(String name, int age, Cat myCat, int[] myArray, List<String> myList, Set<Cat> mySet,
Map<String, String> myMap) {
super();
this.name = name;
this.age = age;
this.myCat = myCat;
this.myArray = myArray;
this.myList = myList;
this.mySet = mySet;
this.myMap = myMap;
}
把无参构造也添加上,养成好习惯
- 复制applicationContext.xml为applicationContext2.xml
- 修改applicationContext2.xml实现构造注入
<?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"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<bean id="cat" class="cn.cdy.springDemo.pojo.Cat">
<property name="name" value="lili"></property>
</bean>
<bean id="cat2" class="cn.cdy.springDemo.pojo.Cat">
<property name="name" value="mimi"></property>
</bean>
<bean id="person" class="cn.cdy.springDemo.pojo.Person">
<constructor-arg name="name" value="大明"></constructor-arg>
<constructor-arg name="age" value="20"></constructor-arg>
<constructor-arg name="myCat" ref="cat2"></constructor-arg>
<constructor-arg name="myArray">
<array>
<value>4</value>
<value>5</value>
<value>6</value>
</array>
</constructor-arg>
<constructor-arg name="myList">
<list>
<value>菠萝</value>
<value>蜜桃</value>
</list>
</constructor-arg>
<constructor-arg name="mySet">
<set>
<ref bean="cat"/>
<ref bean="cat2"/>
</set>
</constructor-arg>
<constructor-arg name="myMap">
<map>
<entry key="qq" value="9999"></entry>
<entry key="weixin" value="8888"></entry>
</map>
</constructor-arg>
</bean>
</beans>
- 修改启动类,导入applicationContext2.xml
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("classpath:applicationContext2.xml");
Person p = ac.getBean(Person.class);
System.out.println(p);
}
-
运行
注:此处Cat类添加了toString()方法,所以与上面打印的结果有所不同可以看到,对象也同样可以成功赋值。