通俗讲解spring中 ioc 是如何解决类之间的依赖关系(自建 beanFactory 类来实现)

一. 简介

  对于刚接触Spring的小伙伴肯定对ioc这个名词有很大的困惑。当你在百度搜索什么是ioc的时候,这是百度词条的解释:

控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。

那么IOC是个什么鬼?? 它又怎么可以降低代码之间的耦合度呢?
本文就将带你从最基本的案例一步一步的了解IOC是怎么解决此项问题的。
小伙伴请打开idea 来一起尝试下吧!

二. 案例一:耦合度很高的程序

  如下图所示,我们在idea中创建了一个工程
  此工程的基本逻辑就是表现层调用服务层,服务层调用dao层,dao层来对数据库进行操作。在这里插入图片描述

我们自然而然的会在表现层注入service层的类,service层注入Dao层的类来实现方法的调用。就像这样

表现层:
在这里插入图片描述

service层:
在这里插入图片描述
但是,此种注入对象的方法会导致一个严重的问题:
表现层依赖于服务层,服务层依赖于Dao层

假如我们把Dao层的类删掉,那么此工程就会报错,连编译都不可能比编译!!
在这里插入图片描述

2.1 案例一的解决办法:使用反射为我们创建对象

  为了避免耦合度太高的问题,我们将会自己写一个 BeanFactory 来反射创建对象,这样即使对象不存在,在编写代码的时候,也不会报错

public class BeanFactory {
    
    
    //定义一个Properties对象
    private static Properties props;


    private static Map<String,Object> beans;

    //使用静态代码块为Properties对象赋值
    static {
    
    
        try {
    
    
            //实例化对象
            props = new Properties();
            //获取properties文件的流对象
            InputStream in = BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties");
            props.load(in);
            //实例化容器
            beans = new HashMap<String,Object>();
            //取出配置文件中所有的Key
            Enumeration keys = props.keys();
            //遍历枚举
            while (keys.hasMoreElements()){
    
    
                //取出每个Key
                String key = keys.nextElement().toString();
                //根据key获取value
                String beanPath = props.getProperty(key);
                //反射创建对象
                Object value = Class.forName(beanPath).newInstance();
                //把key和value存入容器中
                beans.put(key,value);
            }


        }
        catch(Exception e){
    
    
            throw new ExceptionInInitializerError("初始化properties失败!");
        }
    }

    /**
     * 根据Bean的名称获取bean对象
     * @param beanName
     * @return
     */
    public static Object getBean(String beanName) {
    
    

        return beans.get(beanName);
    }
  }

2.2 beanFactory 的解释

  在我们自己写的beanFactory中 ,我们通过对象的全限定类名反射创建出对象,然后存在map集合中。

  当我们需要对象时只需要通过getBean方法传入想要创建对象的名字,然后在事先写好的properties中找到此对象名字所对应的全限定类名。最后反射创建对象。

//.properties文件
accountService=com.eric.service.impl.AccountServiceImpl
accountDao=com.eric.dao.impl.AccountDaoImpl
//反射创建对象
  Object value = Class.forName(beanPath).newInstance();

三.案例一的提高:使用beanFactory创建对象

在这里插入图片描述

在这里插入图片描述

四.总结:

  你可以将案例一与案例一的改进进行对比,假如此时你删掉Dao层的代码。 service层,以及表现层是不会报错的

这样不就降低了类与类之间的依赖吗?

  实际的spring也是这样做的,即将对象的控制权交给spring的ioc容器,而不需要我们手动 new 对象

  我们将对象包装成bean对象交给IOC容器管理,这就是IOC的定义–控制反转

猜你喜欢

转载自blog.csdn.net/qq_44716086/article/details/105918818