• spring IOC原理


    IOC原理:

    1. IOC是什么? 
    2. IOC容器是什么?(IOC容器就是依赖注入技术的核心bean的集合。)
    3. 为什么有IOC?
    4. 要实现IOC需要哪些必要条件?

    一般大家提到spring都知道他的2大功能,一个是IOC叫控制反转,更准确的应该叫依赖注入,另一个便是AOP,这里不讨论AOP。

    那么如何实现IOC,早期注解还不是很流行的时候,大家肯定配置过spring的配置文件,applicationContext.xml(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"
     xmlns:context="http://www.springframework.org/schema/context"
     xmlns:tx="http://www.springframework.org/schema/tx"
     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"
     default-autowire="byName" default-lazy-init="true">
    <bean     class="bean的完全限定名"
              name/id="bean在容器内的唯一名称"
                scope="bean的生命周期"
                lazy-init="是否为延迟加载"
                init-method="bean的setter被调用之后调用该方法进行初始化"
                destroy-method="容器在销毁该Bean后的调用的方法"
                abstract="是否为抽象Bean,spring对于抽象bean不产生实例,主要用于继承"
                parent="父Bean的名称,会继承父Bean的属性,与Java的Class无任何关系"
                factory-method="工厂方法的名字"
                factory-bean="工厂Bean的名字"
                depends-on ="依赖Bean的名字,保证初始化顺序。” > 
    
                <!-- Constructor-arg给属性赋值写法一 -->
                <constructor-arg type="int" value="10"/>
                <!-- Constructor-arg给属性赋值写法二 -->
                <constructor-arg name="age" value="10"/>
                <!-- Constructor-arg给属性赋值写法三 -->
                <constructor-arg index="0" value="10"/>
    
                <!-- Properties给属性赋值写法一 -->
                <property name="bean1">
                     <ref bean="另外一个bean的id"/>
                </property>
                <!-- Properties给属性赋值写法二 -->
                <property name="bean1" ref="另外一个bean的id"/>
                <!-- Properties给属性赋值写法三 -->
                <property name="age" value="10"/>
    </bean> 

    或者通过注解:

    @Component  进行配置bean;  @Autowired进行bean注入。

    通过配置我们知道<beans>标签下还有多个<bean>,同时bean下面还有<constructor-arg>和<property>,这2个属性分别对应构造器注入和setter注入(这2种是spring推荐的方式)

    另外还有通过bean工厂方式注入的,并不推荐。

    • 这些bean装入容器的时候,<bean>标签下的各种属性(例如:class、id、scope等等属性)该怎么办?
    • 另外分析上面的红色加粗字体,一个体现的是多个bean,一个体现的是bean的注入存在引用关系。既然,IOC容器是装入bean的容器,如果是你,你该怎么将bean装入这个容器呢?
    • 既然是一个容器(能称作容器的必要条件是什么?),里面的bean我们是不是随时可以取用?容器中的bean是不是该有有效时间(对象的生命周期)?

    先看下面的几个例子:

    public class ClassB {
        
        private ClassA classA;
    
        public ClassB(ClassA classA) {
            this.classA = classA;
        }
        
        public String getStr() {
            return classA.getStr();
        }
        
    //    public static void main(String[] args) {
    //        ClassA classA = new ClassA();
    //        ClassB classB = new ClassB(classA);
    //        classB.getStr();
    //    }
    }

     类B通过构造方法能够获取到类A,从依赖上来讲,类B的创建需要依赖类A,这个是从代码上体现,尤其是main方法中,类B进行

    实例的时候必须先获取一个类A的实例(不要纠结无参构造,实际生产中存在这样的关系,B类的功能必须依赖A类),这里体现的

    就是类B依赖类A,这就是依赖的体现,现在将main方法中的显示构造

    ClassA classA = new ClassA();
    ClassB classB = new ClassB(classA);//配置到spring配置文件中,我们就可以不用自己去实例化这个类B就可以直接使用

    替换通过spring配置文件进行配置,这就是注入

    现在,我们从实现配置文件出发开始模拟实现IOC功能(多个bean,并且bean之间有依赖注入关系),

    1. 定义一个配置文件(applicationContext.xml),文件名要有一定的限制(为后面准确读取特定文件准备)ResourceLoader
    2. 获取到这个文件,并且能够读取到里面的内容 XmlBeanDefinitionReader
    3. 文件中的内容要想正确读取,需要一定的格式支持,定义一个数据格式BeanDefinition,格式定义了能够读取的属性(例如:class、id、scope等等属性)
    4. 读取到bean以及bean中的属性,并且正确创建这个bean,我们通过AutowireCapableBeanFactory进行bean的装配
    5. 正确读取到单个的bean和bean之间的引用关系,我们需要 HierarchicalBeanFactory 进行关系的维系。
    6. 将多个bean进行集中管理通过 ListableBeanFactory进行集合管理

    实现的流程大致如图:

    以上就是演变过程,其中定义的接口都是spring源码中的结构,spring  beans包中包含以上所有内容,但是整个的协作过程

    体现在spring context包中,spring core包中包含了实现以上功能的底层实现。

    其中:

    bean的定义:

     

    bean的解析:

    bean的创建:

    • ListableBeanFactory(可列表)
    • HierarchicalBeanFactory(层级关系)
    • AutowireCapableBeanFactory(自动装配)

    这3个接口都是继承自 BeanFactory(很重要)这个顶级接口,最终落地实现类 DefaultListableBeanFactory

    类层级关系如图:

      

    协作过程在ApplicationContext接口中,

     

     最终实现类为 AbstractApplicationContext(核心方法 refresh(),该类为抽象类,部分可定制化内容由实际实现子类完成)

  • 相关阅读:
    7-4
    7-3
    第五章例5-2
    第五章例5-1
    第四章例4-12
    第四章例4-11
    第四章例4-10
    第四章例4-9
    第四章例4-8
    第四章例4-7
  • 原文地址:https://www.cnblogs.com/yangmin86/p/12964004.html
Copyright © 2020-2023  润新知