spring的DI.IoC是什么

Posted 头鹰在学习

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring的DI.IoC是什么相关的知识,希望对你有一定的参考价值。

最近要搞spring的单元测试,不得已啊啊啊啊啊啊啊啊啊又要开始搞spring……

日目晶……

 

搞这几个概念,先甩一部分代码:

UserDao 接口

package com.itheima.ioc;
public interface UserDao {
	public void say();
}

 

该接口实现类UserDaoImpl 

package com.itheima.ioc;
public class UserDaoImpl implements UserDao {
	@Override
	public void say() {
		// TODO Auto-generated method stub
		System.out.println("userDao say hello world");
	}
}

 

  • 控制反转的概念

在一般的设计中,如果要调用UserDaoImpl的say()方法,就要new一个UserDaoImpl类出来,比如以下的方法:

……
UserDaoImpl userDao = new UserDaoImpl();
userDao.say();
……  

 

在spring中呢,有个概念叫IoC(Inversion  of Control 即控制反转),它通过框架设定,可以通过配置文件,在spring的容器(可以理解为一个装满了对象的瓶子)中取一个现成的UserDaoImpl的实例出来,而不需要new一个。

具体做法:

编辑applicationContext.xml,添加一个userDao的bean(可以理解为一个类,添加之后,spring容器中就有这个类的对象)

<?xml version="1.0" encoding="UTF-8"?>
<beans ……>
	<!-- 添加UserDaoImpl实例,id=userDao -->
	<bean id = "userDao" class = "com.itheima.ioc.UserDaoImpl"/>
</beans>

  

调用userDaoImpl的say()方法代码如下:

package com.itheima.ioc;
/**
 * 通过Spring容器来获取实现类对象
 * 而不是通过new
 */
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestIoc {
	public static void main(String[] args) {
		ClassPathXmlApplicationContext applicationContext = 
				new ClassPathXmlApplicationContext("applicationContext.xml");
		UserDao userDao = (UserDao) applicationContext.getBean("userDao");
		userDao.say();
	}
}

  

 

 

 

  • 依赖注入的概念

UserService代码:

package com.itheima.ioc;
public interface UserService {
	public void say();
}

 

UserServiceImpl 实现类:

这里的实现类中,我们要重写say()方法,say()方法有一个现成的UserDaoImpl方法,我们直接拿过来用,一般是这么写的:

public class UserServiceImpl implements UserService {
	UserDao userDao=new UserDaoImpl();
	public void setUserDao(UserDao userDao){
		this.userDao= userDao;
	}
	@Override
	public void say() {
		// TODO Auto-generated method stub
		this.userDao.say();
		System.out.println("userService say hello world~");
	}
}

 

这么写没问题,不过spring容器里面有个现成的UserDaoImpl,还new一个,很浪费,直接拿过来用会更方便。

这个直接拿过来用的搞法,叫DI(Dependency Injection ,即依赖注入)。

依赖注入有两种做法,一个是setter,一个是构造方法,这里只给setter的方法,构造方法的我看的书上还没讲,不想动。

做法如下:

改写UserServiceImpl,把new变成私有属性

public class UserServiceImpl implements UserService {
	//声明UserDao属性
	private UserDao userDao ;
	
	public void setUserDao(UserDao userDao){
		this.userDao= userDao;
	}
	@Override
	public void say() {
		// TODO Auto-generated method stub
		this.userDao.say();
		System.out.println("userService say hello world~");
	}
}

  

编写配置文件,把userDao Bean添加到userService下面:

<beans xmlns="……">
	<bean id = "userDao" class = "com.itheima.ioc.UserDaoImpl"/>
	<bean id = "userService" class = "com.itheima.ioc.UserServiceImpl">
	<!-- 将id=userDao的实例注入到userSericeImpl -->
		<property name="userDao" ref = "userDao"/>
	</bean>
</beans>

  

 

 

 

 

总结:

1.将new转化为从容器中拿,这就是IoC的工作机制,即控制反转+依赖注入,这两个概念可以理解为同一个东西

2.控制权由硬代码new一个实体类,转移到spring容器分配,即为控制反转;

3.spring负责将容器内的对象,注入给调用者,即为依赖注入。

  

以上是关于spring的DI.IoC是什么的主要内容,如果未能解决你的问题,请参考以下文章

Spring 源码学习

spring 中 啥是ioc

接下来我应该学习啥 DI/IoC 框架? [关闭]

面试题中问到 aop di ioc 怎么回答

面试常问Spring IOC,不得不会。

Spring IOC 学习总结