这几天正在复习Spring
的相关内容,同时想要对Spring
的实现原理作一些深刻的研究。今天看了看Spring
中IoC
的实现,找到了一篇很是详细的博客,研究了一个下午,看完以后惟一的感觉就是——太复杂了。Spring
源码中,类和接口的体系很是的复杂,同时方法的实现也是,方法调用感受无穷无尽,甚至相互调用,给我绕的晕晕的。应该是本身目前的技术水平还过低,项目经验也不足,甚至对Spring
的运用都不够熟悉,因此研究源码对我来讲可能仍是太早了。java
虽然对于Spring
的IoC
,我可能连十分之一都尚未弄懂,可是一个下午的研究也不是毫无收获。这篇博客就来简单讲讲我对IoC
的理解,以及Spring
中,IoC
最基本的实现流程。spring
在咱们使用传统的编码方式编写代码时,若是在类中须要引用另一个类的对象,咱们通常会直接在类中使用new
关键字,建立这样一个对象。此时,使用这个对象的类,就与这个对象所对应的类产生了耦合性。c#
IoC
中文名称为控制反转,它就是用来解决上述问题的一种设计思想,它能指导咱们设计出耦合性更低,更易于管理的代码。传统的程序,都是在须要使用的地方主动地建立对象,而IoC
的思想倒是将建立对象的工做交给IoC
容器去进行。咱们告诉IoC
容器,它须要建立那些对象,IoC
容器建立好这些对象,而后主动地将它们注入到须要使用的地方。此时,须要使用对象的那些类,并不主动地获取对象,并且由IoC
容器为它们分配,控制权在IoC
容器手上,这就是控制反转。固然,IoC
容器并不仅是控制对象,能够理解为控制外部资源的获取。oop
IoC
很好的体现了面向对象设计法则之一—— 好莱坞法则:“别找咱们,咱们找你”;即由IoC
容器帮对象找相应的依赖对象并注入,而不是由对象主动去找。post
DI
中文名称为依赖注入,它其实和IoC
是相同的概念,或者能够理解为它是IoC
的一种具体的实现方式。IoC
的概念可能比较模糊,控制反转只是一种思想,可能仅仅只是停留在由其余组件控制对象,而不是在使用的地方直接建立这一层面,可是具体如何实现并无指明。而DI
就是它的一种实现思路,由容器建立对象,并主动将对象注入到须要使用它的地方。2.1
中对IoC
的解释,实际上更加偏向于DI
。学习
这一块,我就简单地说一说我今天下午在研究Spring
的IoC
源码的过程当中,了解到的一些内容。首先,Spring
的IoC
容器,能够简单地理解为就是BeanFactory
接口的一个实现类对象,好比Spring
的应用上下文接口ApplicationContext
就是继承自BeanFactory
,而咱们使用较多的ClassPathXmlApplicationContext
就是ApplicationContext
的一个实现类。它们均可以理解为是Spring
的IoC
容器,而BeanFactory
就是这个继承体系中的最高层。下面我就以单例bean的建立,简单地说一说Spring
的IoC
实现的一个过程,假设使用到的是ClassPathXmlApplicationContext
这个容器,解析的是xml
配置文件:编码
xml
配置文件,将声明在xml
文件中的bean
的配置信息提取出来,每个bean
的配置信息被封装成一个BeanDefinitionHolder
对象。BeanDefinitionHolder
主要包含三个成员——BeanDefinition
对象,bean
的名称(id
),以及bean
的别名。BeanDefinition
对象就是用来保存一个bean
的配置信息,好比bean
的做用域,bean
的类型,bean
的依赖,bean
的属性......ConcurrentHashMap
对象,这个map
的key
是bean
的名称,而value
则是BeanDefinition
对象的引用。容器将第一步中解析出的每个BeanDefinitionHolder
对象,它对应的bean
名称,以及拥有的BeanDefinition
引用放入这个map
中。因此,这个map
保存了咱们在程序中声明的全部的bean
的配置信息。bean
,遍历第二步中的map
集合,获取到bean
的名称以及对应的BeanDefinition
对象,经过BeanDefinition
对象中的信息,判断这个bean
有没有定义为延迟加载,若没有,则须要如今就进行建立。在建立前,先经过BeanDefinition
中的配置信息,判断此bean
有没有depend-on
(依赖)其余bean
,如有,则先建立当前bean
依赖的bean
(此处的depend-on
不是bean
的属性,而是须要经过配置项进行配置的)。以后,则建立当前遍历到的bean
。bean
在建立完成后,经过bean
的BeanDefinition
对象,获取bean
须要注入值的属性,而后为属性赋值,若属性的值类型是其余的bean
,则以上面相同的步骤,建立属性对应的bean
;ConcurrentHashMap
,将建立好的单例bean
保存在其中。咱们在代码中能够经过容器的getBean
方法,传入bean
的名称或类型获取单例bean
。容器会先去这个map
中查找,若map
中不存在,且这个bean
的配置在第2
步中存储配置信息的map
中可以找到,则建立这个bean
,放入存储bean
的map
中(由于bean
能够配置延迟加载,即第一次获取时加载); Spring
中,bean
最基本的两种做用域就是singleton
(单例)和prototype
(多例),默认为单例。以上过程是单例bean
的建立过程,若做用域为prototype
,则每一次调用getBean
方法,都会建立一个新的bean
。顺带一提,建立bean
的方式是经过反射机制,这个大部分人应该都知道。prototype
以上内容是我根据本身的认识,对Spring
的IoC
作的一次简单记录,内容并不全面,由于我目前对它的理解也比较浅显。在今天阅读Spring
源码的过程当中,我发现它真的比我想象中要复杂不少,或许是我水平有限,又或许是没有掌握阅读源码的方法,读起来真的很是吃力。总而言之,想要真正读懂Spring
,我还须要不少的学习,但愿从此可以尽快提高本身,早日将Spring
吃透。设计