Spring入门之Spring IOC和DI 理解原理

本文深入探讨了Spring框架中的IOC(控制反转)和DI(依赖注入)概念,通过具体示例解释了这两种设计思想的工作原理,以及它们如何改变对象创建和依赖管理的传统方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.举例说明问题

1.1 例子1

以往我们需要一个对象的时候,我们通常都是自己去new一个。例如
我有个Person类,我需要一个对象时,我直接new一个对象然后去使用。
示例代码:

Person p = new Person();
p.setName("张三");
p.hello();

public class Person {
    private String name;
    private int age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public void hello(){
        System.out.println("hello:"+name);
    }
结果打印:hello:张三

现在我们有了spring框架,当我再需要一个对象时,不用我们直接去new,而是向外部容器申请一个,直接拿来使用。

1.2 例子2

再举个例子,(习惯性的举例子)
现在我们需要一个房子,通常我们不会是自己画图纸、建房子、装修最后入驻,这个过程是非常复杂的,我们必须自己设计和面对每一个环节。

通常我们是找一个中介,中介给我们介绍房子,中介就会按照我们的要求给我们提供房子,
我们直接拎包入住(直接使用。)就行。简单明了,如果房子我们不符合我们的要求,我们就抛出异常。整个过程不再是我们自己控制,而是由中介来控制。
也就是说我们不负责对象本身的创建与维护,(对象由外部容器来创建)我们直接使用。
Spring开发方式就是这样: 所有的类都会在spring容器中登记,告诉spring你是什么东东,你需要什么东东,然后spring会在系统运行适当的时候,把你要的东西主动给你,同时也把你交给需要你的东东。 所有类的创建、维护、销毁都是由spring来控制。

我们结合找房子的例子与IOC容器对象起来。
我们想买房子,我们直接去找中介,中介给我们介绍房子,然后我们直接入住。
对于IOC,当我们想使用对象时,我们直接找IOC容器,容器给我们返回对象,我们直接使用对象。
在这里插入图片描述
那么我们一直在说spring的IOC 容器,ioc容器 管理并创建对象,在使用过程中,是从容器中拿出对象直接使用。

2. IOC是什么

总结一下:

Ioc—Inversion of Control,即“控制反转”,不是什么技术,而是一种设计思想。在Java开发中,Ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制。如何理解好Ioc呢?理解好Ioc的关键是要明确“谁控制谁,控制什么,为何是反转(有反转就应该有正转了),哪些方面反转了”,

结合我们上述举的例子,可以得到如下答案:

  1. 谁控制谁:在传统的开发模式下,我们都是采用直接 new 一个对象的方式来创建对象,也就是说你依赖的对象直接由你自己控制,但是有了 IOC 容器后,则直接由 IoC 容器来控制。所以“谁控制谁”,当然是 IoC 容器控制对象。
  2. 控制什么:控制对象。
  3. 为何是反转:没有 IoC 的时候我们都是在自己对象中主动去创建被依赖的对象,这是正转。但是有了 IoC 后,所依赖的对象直接由 IoC 容器创建后注入到被注入的对象中,依赖的对象由原来的主动获取变成被动接受,所以是反转。
  4. 哪些方面反转了:所依赖对象的获取被反转了。

3.DI是什么

Dependency Injection “依赖注入”:是组件之间依赖关系由容器在运行期决定的。

依赖注入DI其实是IOC的实现方式,IOC容器在初始化的时候,会创建一系列对象,同时能够把这些对象之间的依赖关系通过注入的方式组织起来。
理解DI的关键是:“谁依赖谁,为什么需要依赖,谁注入谁,注入了什么”,那我们来深入分析一下:

谁依赖于谁:当然是应用程序依赖于IoC容器;
为什么需要依赖:应用程序需要IoC容器来提供对象需要的外部资源;
谁注入谁:很明显是IoC容器注入应用程序某个对象,应用程序依赖的对象;
注入了什么:就是注入某个对象所需要的外部资源(包括对象、资源、常量数据)。
扩展理解:

在这里插入图片描述

4.IOC容器中Bean的配置

spring IOC管理的对象都称为bean,
Bean的配置形式有两种,基于XML文件的方式;基于注解的方式。
本文是以XML文件的方式进行说明。
新建一个spring的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">
    <bean id="person" class="com.diligentkong.bean.hello.Person">
        <property name="name" value="张三"></property>
    </bean>
</beans>

获取方式:

public static void main(String[] args) {

   /*原始方式

    // 创建 Person 的一个对象
   Person p = new Person();
    // 为name赋值
   p.setName("张三");
   // 调用hello方法
   p.hello();

    */

//Spring的方式的调用

   //创建spring的IOC容器对象
     ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
     // 从IOC容器中获取Bean 实例
     Person per = (Person) ac.getBean("person");
     // 调用hello方法
     per.hello();
 }

先看配置文件
在xml文件中通过bean节点来配置bean,

<bean id="person" class="com.diligentkong.bean.hello.Person">
        <property name="name" value="张三"></property>
 </bean>

id:标识容器中的bean ,id唯一。
       若 id 没有指定,Spring 自动将权限定性类名作为 Bean 的名字
       id 可以指定多个名字,名字之间可用逗号、分号、或空格分隔
class: bean的全类名,通过反射的方式在IOC容器中创建bean,所以要求Bean中必须有无参的构造器

我们先看获取xml的这一步,

//创建spring的IOC容器对象
  ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");

在Person中写一个无参构造函数,set方法中打印输出

public class Person {
    private String name;
    private int age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        // 新添加的
        System.out.println("setName:" +name);
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public void hello(){
        System.out.println("hello:"+name);
    }

    //新添加的
    public Person() {
        System.out.println("Person Constructor...");
    }
}

Test方法中

//创建spring的IOC容器对象
  ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
  // 从IOC容器中获取Bean 实例
 // Person per = (Person) ac.getBean("person");
  // 调用hello方法
 // per.hello();

输出的内容:
在这里插入图片描述

也就是说 spring创建IOC容器的时候,会调用构造器,并调用set方法为属性赋值

在 Spring IOC 容器读取 Bean 配置创建 Bean 实例之前, 必须对它进行实例化. 只有在容器实例化后, 才可以从 IOC 容器里获取 Bean 实例并使用.

借鉴的博客:https://www.cnblogs.com/xdp-gacl/p/4249939.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值