1、什么是DI依赖注入?
spring动态的向某个对象提供它所需要的其他对象。这一点是通过DI(Dependency Injection,依赖注入)来实现的。比如对象A需要操作数据库,以前我们总是要在A中自己编写代码来获得一个Connection对象,有了 spring我们就只需要告诉spring,A中需要一个Connection,至于这个Connection怎么构造,何时构造,A不需要知道。在系统运行时,spring会在适当的时候制造一个Connection,然后像打针一样,注射到A当中,这样就完成了对各个对象之间关系的控制。A需要依赖 Connection才能正常运行,而这个Connection是由spring注入到A中的,依赖注入的名字就这么来的。那么DI是如何实现的呢? Java 1.3之后一个重要特征是反射(reflection),它允许程序在运行的时候动态的生成对象、执行对象的方法、改变对象的属性,spring就是通过反射来实现注入的。
简单来说什么是依赖注入,就是给属性赋值(包括基本数据类型和引用数据类型)
2、利用 set 方法给属性赋值
第一步:创建工程,并导入相应的 jar 包
第二步:创建实体类 Person
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
|
package
com.ys.di;
import
java.util.List;
import
java.util.Map;
import
java.util.Properties;
import
java.util.Set;
public
class
Person {
private
Long pid;
private
String pname;
private
Student students;
private
List lists;
private
Set sets;
private
Map maps;
private
Properties properties;
public
Long getPid() {
return
pid;
}
public
void
setPid(Long pid) {
this
.pid = pid;
}
public
String getPname() {
return
pname;
}
public
void
setPname(String pname) {
this
.pname = pname;
}
public
Student getStudents() {
return
students;
}
public
void
setStudents(Student students) {
this
.students = students;
}
public
List getLists() {
return
lists;
}
public
void
setLists(List lists) {
this
.lists = lists;
}
public
Set getSets() {
return
sets;
}
public
void
setSets(Set sets) {
this
.sets = sets;
}
public
Map getMaps() {
return
maps;
}
public
void
setMaps(Map maps) {
this
.maps = maps;
}
public
Properties getProperties() {
return
properties;
}
public
void
setProperties(Properties properties) {
this
.properties = properties;
}
}
|
我们看到这个实体类包括引用类型 Student 类,基本数据类以及集合数据类型。
第三步:在 applicationContext.xml 中进行赋值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
|
<!--
property是用来描述一个类的属性
基本类型的封装类、String等需要值的类型用value赋值
引用类型用ref赋值
-->
<bean id=
"person"
class
=
"com.ys.di.Person"
>
<property name=
"pid"
value=
"1"
></property>
<property name=
"pname"
value=
"vae"
></property>
<property name=
"students"
>
<ref bean=
"student"
/>
</property>
<property name=
"lists"
>
<list>
<value>
1
</value>
<ref bean=
"student"
/>
<value>vae</value>
</list>
</property>
<property name=
"sets"
>
<set>
<value>
1
</value>
<ref bean=
"student"
/>
<value>vae</value>
</set>
</property>
<property name=
"maps"
>
<map>
<entry key=
"m1"
value=
"1"
></entry>
<entry key=
"m2"
>
<ref bean=
"student"
/>
</entry>
</map>
</property>
<property name=
"properties"
>
<props>
<prop key=
"p1"
>p1</prop>
<prop key=
"p2"
>p2</prop>
</props>
</property>
</bean>
<bean id=
"student"
class
=
"com.ys.di.Student"
></bean>
|
第四步:测试
1
2
3
4
5
6
7
8
9
10
11
|
//利用 set 方法给对象赋值
@Test
public
void
testSet(){
//1、启动 spring 容器
//2、从 spring 容器中取出数据
//3、通过对象调用方法
ApplicationContext context =
new
ClassPathXmlApplicationContext(
"applicationContext.xml"
);
Person person = (Person) context.getBean(
"person"
);
System.out.println(person.getPname());
//vae
}
|
3、利用 构造函数 给属性赋值
第一步:在实体类 Per'son.java 中添加两个构造方法:有参和无参
1
2
3
4
5
6
7
|
//默认构造函数
public
Person(){}
//带参构造函数
public
Person(Long pid,Student students){
this
.pid = pid;
this
.students = students;
}
|
第二步:在 applicationContext.xml 中进行赋值
1
2
3
4
5
6
7
8
9
10
11
12
13
|
<!-- 根据构造函数赋值 -->
<!--
index 代表参数的位置 从
0
开始计算
type 指的是参数的类型,在有多个构造函数时,可以用type来区分,要是能确定是那个构造函数,可以不用写type
value 给基本类型赋值
ref 给引用类型赋值
-->
<bean id=
"person_con"
class
=
"com.ys.di.Person"
>
<constructor-arg index=
"0"
type=
"java.lang.Long"
value=
"1"
>
</constructor-arg>
<constructor-arg index=
"1"
type=
"com.ys.di.Student"
ref=
"student_con"
></constructor-arg>
</bean>
<bean id=
"student_con"
class
=
"com.ys.di.Student"
></bean>
|
第三步:测试
1
2
3
4
5
6
7
|
//利用 构造函数 给对象赋值
@Test
public
void
testConstrutor(){
ApplicationContext context =
new
ClassPathXmlApplicationContext(
"applicationContext.xml"
);
Person person = (Person) context.getBean(
"person_con"
);
System.out.println(person.getPid());
//1
}
|
总结:
1、如果spring的配置文件中的bean中没有<constructor-arg>该元素,则调用默认的构造函数
2、如果spring的配置文件中的bean中有<constructor-arg>该元素,则该元素确定唯一的构造函数