IoC底层原理

前沿:

  • 控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,可以用来降低代码之间的耦合度。其中最常见的方式叫做依赖注入(Dependency Injection,简称DI),还有一种方式叫“依赖查找”(Dependency Lookup)。IoC可以认为是一种全新的设计模式,但是理论和时间成熟相对较晚,并没有包含在GoF中。
  • Class A中用到了Class B的对象b,一般情况下,需要在A的代码中显式的new一个B的对象。
    采用依赖注入技术之后,A的代码只需要定义一个私有的B对象,不需要直接new来获得这个对象,而是通过相关的容器控制程序来将B对象在外部new出来并注入到A类里的引用中。而具体获取的方法、对象被获取时的状态由配置文件(如XML)来指定。 也就是说把对象创建和对象之间的调用过程,交给了Spring进行管理。

一. 底层主要用到的技术

  • xml解析
  • 工厂模式
  • 反射

现在我们开始讲解:
先看如下代码:

public class Person {
    public void eat(){
        System.out.println("吃饭!");
    }
}

public class Student {
    private Person person = new Person();

    public void eatForStudent(){
        person.eat();
        System.out.println("喝牛奶!");
    }
}

在Student类中需要用到Person,此时我们一般的做法是在Student类中new一个Person的对象,然后通过这个对象去调用其方法,但是我们是否想过,如果Person类发生的改变,比如类名发生了改变,类的路径发生了改变,假如说其他类中也创建了Person对象,如果在其他的类中也创建了Person类对象,这个时候就需要大量的改类路径或者名称,很麻烦了,这个时候我们可以用到如下的工厂模式去解决这个问题:

public class PersonFactory {
    public static Person getPerson(){
        return new Person();
    }
}

public class Student {
    private Person person = PersonFactory.getPerson();

    public void eatForStudent(){
        person.eat();
        System.out.println("喝牛奶!");
    }
}

然后在Student类中去调用getPerson方法返回Person类对象,把创建对象的过程交给工厂类PersonFactory来做,如果其他类中也都调用PersonFactory类中的getPerson方法来获取Person类对象,那么如果Person的类路径或者类名改变了,也只需要改变一处即可,也就是改变getPerson方法中的类名称或类路径。

在用了工厂模式之还是有一定的耦合度,此时我们就需要我们的IOC原理,把耦合度降低到最低,在这个过程中除了用到工厂模式外,还需要用到xml解析加上反射。

二.IOC原理过程

步骤一:xml配置文件,配置创建的对象
<bean id="person" class="iocprinciple.Person"></bean>
步骤二:创建工厂类(在工厂模式的基础上利用xml解析加上反射来创建Person类的对象)
public class PersonFactory {
    public static Person getPerson() throws Exception {
        //Dom4j xml解析获取类的全路径
        String classPath = new ClassPathXmlApplicationContext("bean1.xml").getClassPath("person");

        //通过反射得到类的字节码文件
        Class clazz = Class.forName(classPath);

        //调用方法得到对象
        Person person = (Person)clazz.newInstance();

        return person;
    }

}

Person类内容不变,Student变为如下:

public class Student {
    private Person person;
    
    public void eatForStudent(){

        try {
            person = PersonFactory.getPerson();
        } catch (Exception e) {
            e.printStackTrace();
        }

        person.eat();
        System.out.println("喝牛奶!");
    }
}

用到Dom4j的xml解析类如下:

import java.io.InputStream;
import java.util.List;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

public class ClassPathXmlApplicationContext {
    private String configFilePath;

    public ClassPathXmlApplicationContext(String configFilePath) {
        this.configFilePath = configFilePath;
    }

    /*
     * dom4j解析
     */
    public String getClassPath(String id) throws Exception {
        String classPath = null;
        // 解析xml
        SAXReader reader = new SAXReader();
        InputStream inputStream = ClassLoader.getSystemResourceAsStream(configFilePath);
        Document document = reader.read(inputStream);
        if (document == null) {
            return null;
        }
        // 从项目根目录下读取
        Element root = document.getRootElement();

        // 获取节点资源
        List<Element> list = root.elements();
        if (list.size() <= 0) {
            return null;
        }
        for (Element element : list) {
            String idString = element.attributeValue("id");
            if (id.equals(idString)) {
                // 获取bean的class地址
                classPath = element.attributeValue("class");
                break;
            }
        }
        return classPath;
    }

}

这就是spring中IoC的底层原理,在之后的使用过程中,我们只需要写好spring的xml配置文件就可以啦,Spring已经为我们写好了这些关于IoC底层的代码。

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MrYuShiwen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值