打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Spring源码解析IOC过程详解

IOC和DI说明

IOC(Inversion of Control)控制反转:所谓控制反转,就是把原先我们代码里面需要实现的对象创

建、依赖的代码,反转给容器来帮忙实现。那么必然的我们需要创建一个容器,同时需要一种描述来让

容器知道需要创建的对象与对象的关系。这个描述最具体表现就是我们可配置的文件。

DI(Dependency Injection)依赖注入:就是指对象是被动接受依赖类而不是自己主动去找,换句话说

就是指对象不是从容器中查找它依赖的类,而是在容器实例化对象的时候主动将它依赖的类注入给它。

可能有很多官方的解释,但我所理解的IOC容器,其实就可以理解成spring维护的一个Map<String,Object>。各个对象之间的关系以及所有的bean的信息,都由spring Ioc容器来储存,实例的生命周期由IOC容器控制。当然,若想要spring帮你管理,那你就必须按照spring的规则来,其中比较常用的两种方式是xml和注解方式。

Spring 架构图

本文主要讲述的是最下边的Core container模块,也是spring的核心模块

Spring 核心容器体系结构

  1. BeanFactory
  2. UML图:

  1. Spring的顶层接口是BeanFactory,其中最熟悉和最重要的方法就是这个接口定义的,Spring中所有的bean工厂必须实现beanFactory接口。可以发现最终的默认实现类是DefaultListableBeanFactory
  2. 为何要定义这么多层次的接口呢?
  3. 查阅这些接口的源码和说明发现,每个接口都有他使用的场合,它主要是为了区分在Spring内部在操作过程中对象的传递和转化过程中,对对象的数据访问所做的限制。例如ListableBeanFactory 接口表示这些Bean 是可列表的,而HierarchicalBeanFactory 表示的是这些Bean 是有继承关系的,也就是每个Bean 有可能有父Bean。AutowireCapableBeanFactory接口定义Bean的自动装配规则。这地方也就是典型的工厂模式。
  4. BeanDefinition
  5. 这个接口是定义了类的定义,我们所配置的资源最终就是就要转化为符合这个接口定义的实例,接下来看一下BeanDefinition的作用:
DefaultListableBeanFactory中有一个成员变量 private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap(256);在注册阶段变化给其赋值,将xml或者其他的配置转换为spring能理解的数据结构从而可以在getbean阶段可以得到实例。

  1. Bean 的解析过程非常复杂,功能被分的很细,因为这里需要被扩展的地方很多,必须保证有足够的灵
  2. 活性,以应对可能的变化。Bean 的解析主要就是对Spring 配置文件的解析。这个解析过程主要通过下
  3. 图中的类完成:

  1. FactoryBean
  2. 一般情况下,Spring通过反射机制利用的class属性指定实现类实例化Bean,在某些情况下,实例化Bean过程比较复杂,如果按照传统的方式,则需要在中提供大量的配置信息。配置方式的灵活性是受限的,这时采用编码的方式可能会得到一个简单的方案。Spring为此提供了一个org.springframework.bean.factory.FactoryBean的工厂类接口,用户可以通过实现该接口定制实例化Bean的逻辑。FactoryBean接口对于Spring框架来说占用重要的地位,Spring自身就提供了70多个FactoryBean的实现。它们隐藏了实例化一些复杂Bean的细节,给上层应用带来了便利。从Spring3.0开始,FactoryBean开始支持泛型,即接口声明改为FactoryBean的形式
  3. 以Bean结尾,表示它是一个Bean,不同于普通Bean的是:它是实现了FactoryBean接口的Bean,根据该Bean的ID从BeanFactory中获取的实际上是FactoryBean的getObject()返回的对象,而不是FactoryBean本身,如果要获取FactoryBean对象,请在id前面加一个&符号来获取,使用factorybean可以解决Spring本身的bean由ioc容器管理。

主线说明

Spring在IOC和DI的过程主要分为两步:

1. IOC容器初始化

2. 依赖注入getbean

IOC初始化步骤

  1. 定义
  2. 加载
注册
  1. Spring整个加载的整个流程我们分为三步,定义,加载,注册。具体分析代码如何通过一种怎样思
  2. 想和设计模式来实现这三个过程。
  3. 代码运行关键位置的流程图:


  1. 下面我们以一个xml的配置来解析整个过程:
<bean id='helloWorld' class='org.czx.spring.ioc.HelloWorld'> <property name='name' value='Spring'></property></bean>

使用xml的ClassPathXmlApplicationContext的refresh()方法,初始化,加载资源

xml解析,转换为docment对象,然后解析docment对象,对于不同element节点进行做不同的处理,最后转换成BeanDefinition的定义格式,根据id等其他唯一标识,将bean的定义存入缓存中,完成IOC容器的初始化。这个是主线,对于校验,多种格式的解析,是否单例处理,这些就需要看具体处理逻辑了。至此就完成了初始化阶段,所以可以看出来初始化阶段容器并不会去生成对象,除非bean配置lazy-init=ture;

依赖注入getbean

当我们调用getbean方法时候就会触发依赖注入了,将属性值或者属性对象都会根据配置去生成,spring生成的对象怎样一切依赖的配置,spring并不干涉。

依赖注入流程:

依赖注入过程就是生成一个对象,将属性和配置的value值进行对应,然后使用工厂去生成,在这里大量使用策略模式,对于不同对象需要不同的模型去产生。还有一个金典的地方需要注意的是产生的并不是一个我们定义的对象,spring巧妙的运用了装饰器模式定义一个BeanWrapper,最后产生的bean都是beanWrapper,这个beanwrapper是bean的一个增强,在docreatebean时候,可以通过反射去生成一个beanWrapper也可以通过动态代理去实现beanWrapper,这也就是为之后spring实现AOP的功能做了铺垫。

结语

对于Spring ioc的很多细节没有说明,源码需要自己去看才知道细节的实现,对于spring的ioc和di的具体实现,可以看看github上简要的实现:

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
死磕Spring之IoC篇 - 深入了解Spring IoC(面试题)
Spring 这几道令人混淆的面试题,怎么说?
你简历不写精通吗,你说怎么把Bean塞到Spring容器?
通过Spring注解注册Bean的四种方式
《我想进大厂》之Spring夺命连环10问
Spring IoC 详解(四)
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服