本文首发于cdream个人博客(点击获得更加阅读体验)

欢迎转载,转载请注明出处

作为一个java程序员,保守估计一年里也都有300天要和Spring有亲密接触~~像我这种怕是每天都要撸撸Spring,所以这次也要做个深入了解!这次就来看看Spring是怎么初始化IoC容器的😄

image-20181204223850227

注:阅读本文时一定要在IDE进行跳转

我们都是知道Spring为企业级应用提供了丰富的功能,而这些功能底层都依赖于底层最核心的两种特性IOC和AOP。

IOC实现里主要包括两部分,一个是IOC容器初始化,另外一个是依赖注入,由于两部分是相对独立的部分,所以分成不同文章讲解,本篇主要讲述IOC容器的初始化

一、IoC的概念

控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。其中最常见的方式叫做依赖注入(Dependency Injection,简称DI),还有一种方式叫“依赖查找”(Dependency Lookup)。通过控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体,将其所依赖的对象的引用传递给它。也可以说,依赖被注入到对象中。

上面这个概念是来自维基百科,在Expert Spring MVC and Web FlowExpert One-on-One J2EE without EJB等书中都也是将依赖注入看作是IoC的一种方式。不过有些地方会把IoC和DI看成一个概念(例如Spring in Action、Spring揭密等书),不过没关系,不影响我们理解就可以。

白话版

A类的正常的运行需要B类

没有IoC之前我们在使用A类的某个方法时,总会依赖于B类的一些功能,这样我们就要去new个B对象,有时还要考虑什么时候销毁,什么时候使用单例模式等等,类少了还好管理,这要是多起来真是再聪明的人怕也是要十个头九个大了, 而且A、B之间的依赖关系使各代码紧密耦合,一旦B类的出现问题,或者某天干脆不用B了用C,那是不是A类里的new B()全得换成new C()?想象都觉得累...

有了IoC之后,对象创建都交给第三方容器处理,A中的B通过注入来完成,B出问题了,或者需要换成C了,只要把注入的B换成C就可以(现实开发中B、C可以实现相同的接口解决~所以啊,Spring是面向接口编程鸭)。

Tips
  1. Expert One-on-One J2EE without EJB这本书是spring爸爸Rod Johnson写的,进入Spring的BeanFactory类里面看看作者就是他,哈哈!
  2. public interface ApplicationContext extends EnvironmentCapable,ListableBeanFactory,HierarchicalBeanFactory,MessageSource,ApplicationEventPublisher,ResourcePatternResolver {     /**      * 返回该上下文的id(unique)      */     String getId();      /**      *  返回上下文所属应用的名字      */     String getApplicationName();      /**      * 返回这个上下文友好的名字      */     String getDisplayName();      /**      * 返回上下文首次加载的时间      */     long getStartupDate();      /**      * 返回父类上下文      */     ApplicationContext getParent();      /**      * 功能性的暴露自动装配的工厂,并不常用      */     AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException; } 

    这里面的方法也不多,主要的方法都在继承的接口里

    BeanDifinition:储存 Spring中 Bean的信息,包括各属性名,类名,是否单例等,抽象了我们对 Bean的定义,是让容器起作用的主要数据类型。对 IOC 容器来说,BeanDefinition 就是对控制反转模式中管理的对象依赖关系的数据抽象。

    接下来正式进入IoC容器初始化的分析,以FileSystemXmlApplicationContext为例,下面是FileSystemXmlApplicationContext的继承关系~(这形状,满满的爱啊,哈哈)

    image-20181203195616507

    BeanDefinition的Resource定位

    public class FileSystemXmlApplicationContext extends AbstractXmlApplicationContext {     /**      * 无参构造      */     public FileSystemXmlApplicationContext() {     }     /**      * 传入父类上下文      */     public FileSystemXmlApplicationContext(ApplicationContext parent) {         super(parent);     }