码迷,mamicode.com
首页 > 编程语言 > 详细

springMVC 学习(什么是依赖注入)

时间:2015-04-30 09:01:45      阅读:162      评论:0      收藏:0      [点我收藏+]

标签:spring   依赖注入   

       上一篇博文中,我们学习了springIOC,又称spring控制反转,即将对象的创建销毁等操作交给spring容器来处理,今天学习spring的依赖注入,那么什么是依赖注入,说的通俗一点,就是对属性赋值,也就是说我们利用spring来为我们的类中包含的属性来进行赋值,想想之前我们是通过这样的方式来编写代码的:接口  对象 = new 接口实现类();  再看看我们之前是怎么给属性赋值的

 1.通过set方法

 2.通过构造方法

       今天我们来实现通过spring依赖注入来为类中的变量赋值。首先我新建一个Student.java和一个Teacher.java类,并且提供get和set方法

package com.test.di;

public class Student {
	
	private String name;
	private int id;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
}
package com.test.di;

public class Teacher {
	private String teacherName;
	private Student student;
	public String getTeacherName() {
		return teacherName;
	}
	public void setTeacherName(String teacherName) {
		this.teacherName = teacherName;
	}
	public Student getStudent() {
		return student;
	}
	public void setStudent(Student student) {
		this.student = student;
	}
}
       然后,我们在spring配置文件中来为这些属性赋值:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

	<bean id="student" class="com.test.di.Student">
		<property name="name" value="haha"></property>
		<property name="id" value="12"></property>
	</bean>
	<bean id="teacher" class="com.test.di.Teacher">
		<property name="teacherName" value="teacherWang"></property>
		<property name="student" ref="student"></property>
	</bean>
</beans>
       根据配置文件,我们可以发现,在bean中有个property的配置,其中name就是我要为那个属性赋值,对于属性的值,这里有两种情况:

1.如果是基本类型,直接在value中写上需要赋的值即可

2.如果是引用类型,那么需要使用ref来引用对应的类,对于这个栗子,即student这里ref所引用的student就是第一个student的bean中配置的id。

        接下来,我编写一个测试类,来测试是否成功的为属性注入对应的值DiTest.java

ApplicationContext applicationContext = new ClassPathXmlApplicationContext("com/test/di/applicationContext.xml");
Teacher teacher = (Teacher) applicationContext.getBean("teacher");
Student student = teacher.getStudent();
System.out.println(teacher.getTeacherName());
System.out.println("studentName :"+student.getName()+"==studentId :"+student.getId());
此时打印结果如下:

teacherWang
studentName :haha==studentId :12

     发现这个时候spring容器已经为我们的属性赋值成功了。然而我们却并没有像之前那样调用set方法,或者是构造方法,这里有一点需要说明,就是我们虽然没有自己调用set方法来为属性赋值,但是spring还是会掉用set方法,所以我们如果想对某一个属性进行依赖注入的话,那么我们就需要对该属性写上set方法。

      下面我们为teacher注入一些集合,首先需要做的就是在Teacher.java中声明list,set,map这三个属性,然后为这些属性生成set方法,新增属性如下:

private List<String>lists;
private Set<Integer>sets;
private Map<Integer,String>maps;
然后再spring的配置文件中这样为其赋值:

<bean id="teacher" class="com.test.di.Teacher">
		<property name="teacherName" value="teacherWang"></property>
		<property name="student" ref="student"></property>
		<property name="lists">
			<list>
				<value>one</value>
				<value>two</value>
				<value>three</value>
			</list>
		</property>
		<property name="maps">
			<map>
				<entry key="1" value="firstMap"></entry>
				<entry key="2" value="secondMap"></entry>
				<entry key="3" value="thirdMap"></entry>
			</map>
		</property>
		<property name="sets">
			<set>
				<value>111</value>
				<value>222</value>
				<value>333</value>
			</set>
		</property>	
</bean>
        可以发现这个配置文件写起来和普通的集合对象的形式是很相似的,这里我们都是用的基本的类型来作为集合的泛型,如果使用的是引用类型,这里的配置都有ref对应的属性,只需要将所需要引用的类对象的id写入到ref的值当中即可,举个栗子:

对于list和set如果泛型是引用类型,那么可以这样写:

<ref bean=""/>

而对于map如果类型是引用类型,可以这样写:

<entry key-ref="" value-ref=""></entry>

         好了,是时候验证是否赋值成功了。IocTest.java

ApplicationContext applicationContext = new ClassPathXmlApplicationContext("com/test/di/applicationContext.xml");
Teacher teacher = (Teacher) applicationContext.getBean("teacher");
Student student = teacher.getStudent();
System.out.println(teacher.getTeacherName());
System.out.println("studentName :"+student.getName()+"==studentId :"+student.getId());
		
List<String> lists = teacher.getLists();
for (String string : lists) {
	System.out.println(string);
}
Map<Integer,String>maps = teacher.getMaps();
for(Entry<Integer,String>entry :maps.entrySet()) {
	System.out.println(maps.get(entry.getKey()));
}
Set<Integer>sets = teacher.getSets();
for (Integer integer : sets) {
	System.out.println(integer);
}
此时打印的结果如下:

teacherWang
studentName :haha==studentId :12
one
two
three
firstMap
secondMap
thirdMap
111
222
333

可以发现这个时候spring成功为所有的写了set方法的属性成功赋值了。好了上边的都是利用set方法来为属性赋值的,下面我们来利用构造方法来为属性赋值,我们写一个ClassInfo.java类:

package com.test.di;

public class ClassInfo {
	private String className;
	private Student student;
	public ClassInfo(String className, Student student) {
		super();
		this.className = className;
		this.student = student;
	}
	public String getClassName() {
		return className;
	}
	public Student getStudent() {
		return student;
	}
}


     可以看到此时我们声明了两个属性,一个基本类型的,一个引用类型的,并且书写了构造方法,这时我们就可以在spring配置文件中,利用构造方法来为属性赋值了,在bean的配置中有这样一个配置

<constructor-arg index="" type="" ref="" value=""></constructor-arg>

顾名思义就是根据构造函数来为属性赋值的,说明一下这四个参数的意思:

index:该参数在构造方法中的位置,默认从0开始

type:该参数的类型

ref: 如果该参数是引用类型时候的引用id

value:如果该参数是基本类型时候的值

       知道了每个参数的意思,写起来就很简单了,我的ClassInfo.java对应的bean如下:

<bean id="classInfo" class="com.test.di.ClassInfo">
	<constructor-arg index="0" type="java.lang.String" value="testConstructor"></constructor-arg>
	<constructor-arg index="1" type="com.test.di.Student" ref="student"></constructor-arg>
</bean>
      编写测试代码:

ClassInfo classInfo = (ClassInfo) applicationContext.getBean("classInfo");
System.out.println("classInfo.getClassName():"+classInfo.getClassName());
System.out.println("studentId:"+classInfo.getStudent().getId()+"==studentName"+classInfo.getStudent().getName());
此时会正确的答应出我们设置的信息,如下:

classInfo.getClassName():testConstructor
studentId:12==studentNamehaha

        现在我们已经学会了如何在spring中为属性赋值,如之前所属,我们并没有调用set或者构造方法,却能成功为属性赋值,其实我们是把set方法的调用交给spring来处理了,那么依赖注入又有什么用呢?我们为什么要学习依赖注入?还记得我在该篇最开始写了这样一句话:接口  对象 = new 接口实现类(); 这种方式是我们之前创建对象的方法。现在我举个栗子:

      我新建一个借口BookRead然后建俩个类实现该接口:

package com.test.why.di;

public interface BookRead {
	public void readBook();
}
package com.test.why.di;

public class KindleRead implements BookRead {

	@Override
	public void readBook() {
		System.out.println("use kindle read");
	}
}
package com.test.why.di;

public class PhoneRead implements BookRead {

	@Override
	public void readBook() {
		System.out.println("use phone read");
	}
}
package com.test.why.di;

public class ReadBy {
	private BookRead bookRead;

	public ReadBy(BookRead bookRead) {
		this.bookRead = bookRead;
	}
	
	public void read() {
		bookRead.readBook();
	}
}
    

如果我现在需要先用kindle来读书怎么办呢?按照之前的写法:

BookRead bookRead = new KindleRead();
ReadBy readBy = new ReadBy(bookRead);
readBy.read();
那么问题来了,如果我现在需要利用Phone来读书,那么我是不是需要重新new一个PhoneRead呢。这样做并不是我们要的面向接口编程。接下来我们使用spring的依赖注入来为其优化:

首先将两种读书方式的类,在spring容器中进行配置:

<bean id="kindleRead" class="com.test.why.di.KindleRead">
</bean>
<bean id="phoneRead" class="com.test.why.di.PhoneRead">
</bean>
然后配置ReadBy对应的bean:

<bean id="readBy" class="com.test.why.di.ReadBy">
	<property name="bookRead" ref="kindleRead"></property>
</bean>
        测试:
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("com/test/di/applicationContext.xml");
ReadBy readBy = (ReadBy) applicationContext.getBean("readBy");
readBy.read();

      这里我为readBy注入的是kindleRead,因此这时候我调用readBy.read();方法应该是运行的kindleRead的readBook,其实这里已经做到了面向接口编程,就是我的readBy.read();不需要知道bookRead是什么类型,我只需要调用在read方法中调用bookRead.readBook();方法就可以了,具体以哪种方式来读书,我只需要在spring容器当中进行配置即可,这样做也使得代码更加容易维护。

      好了,今天的springDi就学习到这里了。

      源码下载
















springMVC 学习(什么是依赖注入)

标签:spring   依赖注入   

原文地址:http://blog.csdn.net/mockingbirds/article/details/45372523

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!