分析Spring IoC源码(一)概念

一、定义

  1. 首先,大家都知道spring是一个框架,是一个容器框架,所谓容器,就是一个可以存放东西的“器皿”,跟我们生活中的水桶,碗,奶粉瓶是一样的器皿。
  2. 不同的是存放在这个“器皿”可能不是实体,却是一个抽象的东西,这些东西是什么呢,大家先这样分析,spring的核心思想是IoC,IoC(Inversion of Control)控制反转,我们控制了什么,控制的东西不就是我们放在容器里面的东西吗?反转了什么?
  3. 我们控制的当然是“对象”,就是我们一个个在代码里面的new出来的对象,如果我们不反转,那控制这些对象的主宰应该是程序,用到该对象,我们就是new,再用再new,用10次可能我们需要new10次,如果new出来的对象被别人变更了,不好意思,你可能需要找到10处用到该处的地方,一一修改代码,那么代码耦合性很高,这些new出来的对象的主宰就在于你的程序,好吧,我们现在开始“反转”,我不想把控制权给我们了,或者说给系统了,我们交给第三方,“容器”,程序你以后不要new了,要用的话,容器把里面的“对象”主动送给你用,对,“你们(程序)别来找(new)我(对象),我们去找(注入)你(程序)”,Spring:对象,快到碗里来~~~~。

二、案例

好了,现在大概知道容器里面是什么了,对,容器拿出来的“东西”默认是一个个单例的“实例”。
例如,我想在想在spring容器里面拿出一个“老师(Teacher实例)”,那么容器里面至少记录了一个老师的年龄,性别,擅长的科目,有什么特殊能力等等属性或者技能,相当于老师的“名片”,这样,根据名片我们就可以找到老师,将其“实例化”,然后送到你的身边,让你使用,教你读书。
所以,大家抽象一下,Spring容器里面存放的当然是一些“类”的信息,我们不看源码先分析一下,就根据我们平时使用Spring的经验分析,Spring存放了类的哪些信息呢?
①类名(姓名),该类是否抽象(种别),该类的父类(家庭信息),该类的包名(家庭地址)(基本信息)
②属性,构造函数(否则怎么构造函数注入和Setter注入啊?)
③Annotation(否则你@Controller写这样的注解的时候,它怎么知道他是Controller呢?)

(下图是spring容器管理的一个类“Test.Java”的名片-----“BeanDefinition”)
在这里插入图片描述

这些信息就是类的名片,根据这些信息,我们容器就可以把该类“造”出来,好了,我们现在知道容器存放的是一些类的名片“BeanDefinition”,我们现在来看下Spring IoC的源代码吧~
我们最熟知的就是BeanFactory

在这里插入图片描述
Spring是个容器,它就像一个去这个容器里面取东西的“汤勺”,可以360度无死角的去获取Bean,它也是一个接口,所以他只是定义了“汤勺”的基本性质,我们来看看他的子类,看看具体的一些汤勺吧~

在这里插入图片描述

I Cao,“汤勺”有点多啊,我们看见了我们常用的ApplicationContext,ClasspathXmlApplication等等我们熟知的老朋友,但这些老朋友有个共同的地方就是他们是没有子类的,也就说如果你不继承,他们是final的,子类都有一个特点,他们都很出名(例如国民老公王思聪),但更屌的还是他们的爹(他们的父类),核心的功能都是父类做,子类用就可以了,所以我们打开一个父类看看吧,我们打开一个DefaultListableBeanFactory.java,这个类有点屌
在这里插入图片描述

原来如此,BeanFactory.getBean()其实就是hashMap.get(key),获取class然后反射,或者怎么怎么样就获取了,所以我们初步分析IoC源码,就知道我们要干嘛了,我们要分析的就2点:
①如何put(key,name)到beanDefinitionMap中
②从beanDefinitionMap中如何get(key)
DefaultListableBeanFactory该Beanfactory继承实现关系中,可以看到一些猫腻:
在这里插入图片描述
一个继承,继承了AbstractAutowireCapableBeanFactory,实现了ConfigurableListableBeanFactory,这样就可以有了这2个BeanFactory的功能了,但大家要注意它还实现了
BeanDefinitionRegistry,这个接口看字面意思是"Bean定义的注册",这样Beanfactory就有注册Bean的功能了,打开BeanDefinitionRegistry.java
在这里插入图片描述
可以看出,该接口提供了规范,可以去注册(registerBeanDefinition),消除注册(removeBeanDefinition),获取注册(getBeanDefinition),查看是否有此注册(containsBeanDefinition),获取所有的名称(getBeanDefinitionNames),获取名片的个数(getBeanDefinitionCount),该名片是否正在使用(isBeanNameInUse

到此为止,我们初步知道BeanFactory的功能了,对外,他就是一个容器的“勺子”可以帮我们从Spring这个容器里获取我们要的Bean,对内,他也有去注册,消除注册,维护一些bean的信息等一些功能,它可以很好的维护容器中的beanDefinition

猜你喜欢

转载自blog.csdn.net/weixin_43397326/article/details/83080178