通俗易懂的 Spring IOC 实现原理

 2022-09-01
原文地址:https://www.cnblogs.com/jumpkin1122/p/11565282.html

控制反转

1.概述

Spring有IOC和AOP两个核心。其中IOC我们说的控制反转,也就是将创建对象并生命周期的管理过程交给Spring处理。在开发中不再需要关注对象的创建和声明周期的管理,我们需要式由Spring框架提供,这个由Spring管理创建对象和生命周期的机制称为控制反转。创建对象的权力转给框架,他帮我们创建,我们不再使用new关键自来创建对象。

2.原理

创建过程

在初始化一个Spring容器时,Spring会解析spring的配置文件(applicationContext.xml),从上到下解析到<bean id=””,class=””>时,根据标签中的class属性指定的类的全路径名找到该类并通过反射来创建该类的对象,并创建的对象存入到内置的Map容器中管理,其中存入map中的键是该标签中的id值,值是创建的对象。

获取对象过程

当通过context.getBeans("id值")方法来从容器中获取对象时,根据id从内置的Map中寻找是否有匹配的键值,如果有返回对象,如果没有抛出异常。

提示 :默认情况下,多次获取同一个id的bean对象得到的是同一个对象(默认情况下创建的对象是单例的,如果需要多例可以该标签中设置多例)。如果使用一个类配置多个标签设置不同的id ,每个id都会在内置Map中有一个键值对,其中的值是这个类创建的不同的对象。同一个标签下不允许配置多个同id的<标签>,如果配置会报错。

3.实现

首先创建lib目录导入需要依赖的包并buildpath:这些包可以spring官网下载也可以其他远程仓库可以下载。

提示 :我们这里只是入门使用这种导入方式,后面不需要这样导入,开发中直接maven来自动导入)

202209012330281361.png

依赖包导入后在指定包中创建一个Person类(为了使用创建对象)

    package com.test.spring;
    
    public class Person {
        public void say(String str) {
            System.out.println(str);
        }
    }

然后在src目录下创建spring的配置文件applicationContext.xml。在这个配置文件中实现IOC控制反转,也是创建对象负责这个配置文件,我们不需要自己通过new关键字来创建对象。

    <?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-3.2.xsd">
                <bean id="person" class="com.test.spring.Person"></bean>
    </beans>

在这里我们在<bean id=””,class=””>里面设置我们需要创建对象的类信息,class里面填写我们需要创建类的名,spring容器通过这个类名来找到这个类进行加载,然后通过id来给创建的对象设置id,我们使用的时候通过这个id来找到实力化的对象。id可以自定义设置例如:person1,person2,。。都可以,一般使用类名的小写使用。

注意配置内容中不要多余的空格,会报错的,版本需要一致。按规范来写。

我们配置文件中配置好以后创建Person_test的测试类进行测试:

    package com.test.spring;
    import org.junit.jupiter.api.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    
    public class Person_Test {
        @Test
        /**
         * SpringIOC获取对象
         * <bean id="person" class="com.test.spring.person">
         */
        public void test01() {
            //创建Spring容器对象
            ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
            //通过我们配置文件中面配置的beanid来获取对象:id="person"
            Person p = (Person)context.getBean("person");
            //调用对象的方法,并传人参数
            p.say("Hello SpringIOC");
            p.say("Spring控制反转");
        }
    }

这里的@Test做测试使用的必要需要测试的方法上面插入再通过右键—Run as ---JUnit来Junit的方式运行,打印结果如下:

202209012330292872.png