IOC控制反转的基本思想
为什么要用IOC?
通常对象的控制权在程序身上,比如在基本的Dao层和Service层中
Dao层
//UserDao接口
public interface UserDao {
public void getUser();
}
//UserDaoImpl实现类
public class UserDaoImpl implements UserDao{
public void getUser() {
System.out.println("UserDaoImpl输出getUser");
}
}
Service层
//Service层接口
public interface UserService {
public void getUser();
}
//ServiceImpl实现类
public class UserServiceImpl implements UserService{
//private UserDao userDao = new UserDaoImpl();//每当dao层增加一个实现,比如增加UserDaoMysqlImpl,那么这里就要改成new UserMysqlImpl()
private UserDao userDao;
//这样增加很不方便
//设置一个set方法,设置userDao的实现类
public void SetUserDao(UserDao userDao){
this.userDao=userDao;
}
public void getUser() {
userDao.getUser();
}
}
Test方法
public class MyTest {
public static void main(String[] args) {
//用户调用service层,不需要接触dao层
UserServiceImpl userService = new UserServiceImpl();
//避免因为用户需求,而影响原本的代码,我们不要写死ServiceImpl中的UserDao接口实现类的类型
//通过Setter注入,减少原代码的修改
userService.SetUserDao(new UserDaoMysqlImpl());//设置UserDao的实现类,可以减少因为Dao层加入多一个类,而修改源代码的次数
userService.getUser();
}
}
每当出现一个新的UserDao实现类,那么就需要修改userDao的初始化类型,比如出现UserDaoMysqlImpl,那么就要初始化成UserDaoMysqlImpl()
因此在ServiceImpl类中,对userDao并不直接初始化,通过setter方法设置userDao的实现类型,可以在MyTest方法直接进行设置,把创建对象的控制权交给程序员。
IOC本质
创建对象的主动权从程序本身反转到由第三方控制,控制反转也就是获得依赖对象的方式反转了。
利用IOC控制反转,可以降低耦合度。IOC是Spring的核心内容,可以使用xml配置,也可以使用注解进行配置,新的Spring也可以不通过配置进行实现。
控制反转就是通过描述(xml或注解)并通过第三方去生成或获取特定对象的方式,在Spring中实现控制反转的是IOC容器,其实现方法是依赖注入(DI Dependency Injection)。
实例
//Hello类
public class Hello {
private String str;
public String getStr() {
return str;
}
public void setStr(String str) {
this.str = str;
}
@Override
public String toString() {
return "Hello{" +
"str='" + str + '\'' +
'}';
}
}
//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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--使用Spring来创建对象,在Spring中对象称作bean
在java中 创建对象
类型 变量名 = new 类型()
Hello hello = new Hello();
id= 变量名
class = new的对象
property 相当于给设置对象的属性设置一个值
-->
//对bean进行实例化
<bean id="hello" class="com.hzp.pojo.Hello">
<property name="str" value="Spring"></property>
</bean>
</beans>
//MyTest
public class MyTest {
public static void main(String[] args) {
//获取Spring的上下文对象
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//我们的对象现在都在Spring中管理,我们要使用直接调出来就行
/* applicationContext.xml
<bean id="hello" class="com.hzp.pojo.Hello">
<property name="str" value="Spring"></property>
</bean>
*/
//不用通过new的方式也创建出了一个Hello对象
Hello hello = (Hello) context.getBean("hello");//这里输入在配置文件中设置的bean的id
System.out.println(hello);
}
}
由此实例可以看出使用Spring后,对象由Spring来创建的。
反转:程序本身不创建对象,变成被动的接收对象;
依赖注入:就是利用set方法进行注入,即利用set注入类中属性的值。