Spring IOC

导读:本篇文章讲解 Spring IOC,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

IOC

        Inversion of Control 译为控制反转,是一种设计思想,Spring通过IOC容器来管理所有的Java对象的实例化和初始化,控制对象与对象之间的依赖关系。

由IOC管理的Java对象被称为Spring Bean,他们与通过new关键字创建出来的Java对象没有任何区别。

一个类想要使用另一个类的属性,就需要使用new关键字将后者的对象实例创建出来才能实现属性和方法的调用。即调用者控制着被调用者对象创建的控制权。

在Spring应用中,Java对象创建的控制权是掌握在IOC容器里的,大致步骤如下:

  1. 开发人员通过XML、注解、配置文件等方式将Java对象进行定义。
  2. 当Spring启动时,IOC容器会自动的根据据对象定义将对象创建并管理起来,这个由IOC容器管理的实例被称之为Spring Bean。
  3. 当需要某个Bean时,直接从IOC容器中获取即可,而不需要通过new关键字创建。

控制反转:原本调用者是主动的一方,即需要上面资源直接通过new关键字创建。但是在Spring中,IOC容器掌握着主动权,调用者成了被动的一方,被动的等待IOC容器来创建它所需要的对象。

DI

Spring IOC

        Denpendency Injection 译为依赖注入,Martin Fowler 在 2004 年在对“控制反转”进行解释时提出的。Martin Fowler 认为“控制反转”一词很晦涩,无法让人很直接的理解“到底是哪里反转了”,因此他建议使用“依赖注入”来代替“控制反转”。
        依赖关系是一个对象需要用到另外一个对象,即该对象中存在一个属性在另一个对象。Spring在创建对象的过程中会根据依赖关系,将它依赖的对象也注册到IOC容器中。
        依赖注入本质上是Spring Bean属性注入的一种,只不过这个属性是对象的属性。

IOC工作原理

IOC底层通过工厂模式、反射、XML解析等技术来降低代码的耦合度

  1. 在配置文件中对各个对象以及他们之间的依赖关系进行配置。
  2. IOC容器作为一个工厂,Bean就是产品。
  3. Spring在启动时会加载并解析配置文件,得到对象和他们之间的依赖关系。
  4. IOC利用反射,根据类名生成相应的对象,并根据依赖关系将这个对象注入到他依赖的对象中。

Spring是怎样设计容器的?

Spring IOC

使用 ApplicationContext,它是 BeanFactory 的子类,更好的补充并实现了 BeanFactory 的。

BeanFactory 简单粗暴,可以理解为 HashMap:

  • Key – bean name

  • Value – bean object

但它一般只有 get, put 两个功能,所以称之为“低级容器”。

而 ApplicationContext 多了很多功能,因为它继承了多个接口,可称之为“高级容器”。在下文的搭建项目中,我们会使用它。

Spring IOC

ApplicationContext 的里面有两个具体的实现子类,用来读取配置配件的:

  • ClassPathXmlApplicationContext – 从 class path 中加载配置文件,更常用一些;

  • FileSystemXmlApplicationContext – 从本地文件中加载配置文件,不是很常用,如果再到 Linux 环境中,还要改路径,不是很方便。

当我们点开 ClassPathXmlApplicationContext 时,发现它并不是直接继承 ApplicationContext 的,它有很多层的依赖关系,每层的子类都是对父类的补充实现。

而再往上找,发现最上层的 class 回到了 BeanFactory,所以它非常重要。

代码演示

hello接口

public interface HelloMapper {

    void sayHello();
}

hello接口实现类  —- 业务类

public class HelloMapperImpl implements HelloMapper{

    @Override
    public void sayHello() {
        System.out.println(" something !!!");
    }
}

测试类

    @Test
    public void test(){
        HelloMapper helloMapper = new HelloMapperImpl();
        helloMapper.sayHello();
    }

执行结果

Spring IOC

这是使用传统方式编写的代码,HelloMapperImpl 需要实现接口 HelloMapper,而测试类 test 需要依赖 HelloMapperImpl 这个业务类。所以测试类中就需要创建这个业务类的实例,然后才可以在测试类中使用。

Spring写法

<?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">

    <!-- bean就是java对象实例, 即Spring创建和管理的不是类型而是实例 -->
    <!-- Spring配置文件中的bean其实应该写在Java程序代码中,这段代码通常是new一个对象实例 -->
    <bean id="hello" class="mapper.HelloMapperImpl"/>
</beans>

测试类

    @Test
    public void test(){
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        HelloMapper hello = context.getBean("hello", HelloMapper.class);
        hello.sayHello();
    }

Spring使用步骤:

  1. 找到配置文件。
  2. 加载配置文件。
  3. 解析配置文件中的bean元素,并识别id和class。
  4. 通过反射(Class.forName().newInstance())创建这个bean的实例。
  5. 将id作为key、实例作为value存放进Spring容器中。
  6. getBean取出实例
HelloMapper hello = context.getBean("hello", HelloMapper.class);

// 等价于

HelloMapper hello = class.forName("mapper.HelloMapperImpl").newInstance();

即根据配置文件 <bean> 中的 class属性值通过反射创建对象实例,并将 <bean> id 作为key,实例作为 value 保存在IOC容器中。在需要使用的时候直接从IOC容器中就可以获取到对象实例,而不需要通过new关键字的方式主动获取所依赖的对象实例,即获取对象实例的控制权反转了,不再是主动new,而是从第三方(IOC容器)中获取。

总结

        所有的类都会在Spring容器中登记,告诉Spring你是个什么东西,你需要什么东西,然后spring会在系统运行到适当的时候,把你要的东西主动给你,同时也把你交给其他需要你的东西。
    所有的类的创建、销毁都由 Spring来控制,也就是说控制对象生存周期的不再是引用它的对象,而是Spring。对于某个具体的对象而言,以前是它控制其他对象,现在是所有对象都被spring控制,所以这叫控制反转。
    IOC的一个重点是在系统运行中,动态的向某个对象提供它所需要的其他对象。这一点是通过DI(Dependency Injection,依赖注入)来实现的。
    控制反转IOC(Inversion of Control)是说创建对象的控制权进行转移,以前创建对象的主动权和创建时机是由自己把控的,而现在这种权力转移到第三方。
    DI(依赖注入)其实就是IOC的另外一种说法,控制的什么被反转了?就是:获得依赖对象的方式反转了

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由半码博客整理,本文链接:https://www.bmabk.com/index.php/post/95908.html

(0)

相关推荐

半码博客——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!