Spring学习笔记(一)——控制反转IOC

我们以前写代码是先写一个持久层Dao的接口,并写一个对应的实现类:

public interface UserDao {
     
    public void introduce();
}
public class UserADaoImpl implements UserDao{
     
    public void introduce(){
     
        System.out.println("大家好,我是A");
    }
}

调用的话在写一个业务层Service的接口,再写一个对应的实现类:

public interface UserService {
     
    public void introduce();
}
public class UserServiceImpl implements UserService{
     
    private UserDao userDao = new UserADaoImpl();

    public void introduce(){
     
        userDao.introduce();
    }
}

测试:

public class UserServiceTest {
     
    public static void main(String[] args) {
     
        UserService userService = new UserServiceImpl();

        userService.introduce();
    }
}

Spring学习笔记(一)——控制反转IOC_第1张图片
如果增加一个UserDao的实现类B:

public class UserBDaoImpl implements UserDao{
     
    public void introduce(){
     
        System.out.println("大家好,我是B");
    }
}

此时如果要调用B的话,就必须修改业务层的实现类代码:
Spring学习笔记(一)——控制反转IOC_第2张图片
测试:
Spring学习笔记(一)——控制反转IOC_第3张图片
如果又增加了一个UserDao的实现类,又要去修改Service实现类的代码,如果这种需求非常大,则需要经常修改大量代码,这在实际开发中是根本不适用的,这样的设计耦合性太高。

所以我们应该如何解决呢?

我们可以在需要用到的地方 , 不去实现它 , 而是留出一个接口:
Spring学习笔记(一)——控制反转IOC_第4张图片
测试:
当我们传入A实现类:
Spring学习笔记(一)——控制反转IOC_第5张图片
传入B实现类:
Spring学习笔记(一)——控制反转IOC_第6张图片

这里已经发生了根本性的变化,很多地方都不一样了。仔细思考就会发现,以前所有东西都是由业务层(被调用者)去进行控制创建new出来的,而现在是由测试方(调用者)自行控制创建什么对象,把主动权由被调用者交给了调用者,程序不用去管怎么创建怎么实现了,它只负责提供一个接口。

这种思想,从本质上解决了问题,我们程序员不再去管理对象的创建,更多的去关注业务的实现,耦合性大大降低,这也就是IOC的原型 !

控制反转IOC(Inversion of Control) 是一种设计思想,依赖注入DI是实现IOC的一种方法。在没有控制反转的程序中,我们使用面向对象编程,对象的创建与对象间的依赖关系完全写死在程序中,对象的创建由程序自己控制,控制反转后将对象的创建转移给第三方。

控制反转反转的就是:创建依赖对象的控制权由被调用者反转到调用者

现在我们 使用Spring的IOC来解决 上面的问题,首先写一个配置文件:

<?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
        https://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="UserADaoImpl" class="dao.UserADaoImpl"></bean>
    <bean id="UserBDaoImpl" class="dao.UserBDaoImpl"></bean><bean id="UserServiceImpl" class="service.UserServiceImpl">
        <!--ref:引用Spring容器中创建好的对象, value:设置具体的值,基本数据类型和String类型-->
        <property name="userDao" ref="UserADaoImpl"></property>
    </bean>
</beans>

修改测试代码:
Spring学习笔记(一)——控制反转IOC_第7张图片
此时如果我们想要输出B实现类,只要修改配置文件即可:
Spring学习笔记(一)——控制反转IOC_第8张图片
测试:
Spring学习笔记(一)——控制反转IOC_第9张图片
如果需要再添加一个UserDao的实现类,只需要在beans.xml配置对应的bean即可,如果需要调用它,也不需要修改被调用方和调用方的代码,只需要对配置文件进行修改即可,这大大降低了程序的耦合性。

上述依赖对象UserADaoImpl、UserBDaoImpl是由Spring来创建的,UserServiceImpl的属性由Spring容器设置,这个过程就是控制反转。
控制:谁来控制对象的创建,传统应用程序的对象由程序本身控制创建,使用Spring后,对象由Spring来创建
反转:程序本身不创建对象,而变成被动的接收对象

依赖注入DI:本质是通过set方法来进行注入的
当我们把UserServiceImpl中的set方法注释掉,再测试就会发现程序出现异常:
Spring学习笔记(一)——控制反转IOC_第10张图片
Spring学习笔记(一)——控制反转IOC_第11张图片

IOC是Spring框架的核心内容,使用多种方式完美的实现了IOC,可以使用XML配置,也可以使用注解,新版本的Spring已经可以零配置实现IOC。

Spring容器在初始化时先读取配置文件,根据配置文件或元数据创建并组织对象存入容器中,程序使用时再从容器中取出需要的对象。

采用XML方式配置Bean的时候,Bean的定义信息是和实现分离的,而采用注解的方式可以把两者合为一体,Bean的定义信息直接以注解的形式定义在实现类中,从而达到了零配置的目的。

控制反转是一种通过描述(XML或注解)并通过第三方去生产或获取依赖对象的方式。在Spring中实现控制反转的是IOC容器,而IOC容器的实现方法是依赖注入(Dependency Injection,DI)。

你可能感兴趣的:(Spring学习,SSM框架学习)