0%

spring源码总结

spring源码总结

spring源码总结

spring使用场景:编写登录功能。此功能由多个类的对象互相调用实现。一个对象调用另一个对象,Controller调用Service。不使用spring,Controller调用Service,调用之前需要UserService userService = new UserService()

spring源码做了什么:管理类的实例化对象

如何做的

  • 对不同对象的处理。

    首先初始化的时候,即项目启动,加载所有的xml文件存为Bedifinition对象

    • 非延迟加载的单例对象,初始化的时候new出来放在IOC容器中。
    • 延迟加载的单例对象,第一次调用的时候new 出来放在IOC容器中。
    • 多例对象,在使用时根据Bedifinition将对象new出来,返回给调用方。
  • AbstractApplicationContext定义了管理对象的流程。referesh有12个步骤.关键是第2步和第11步。

    • 第2步加载xml配置文件为Bedifinition对象
      • 创建IOC容器DefaultListableBeanFactory
      • 加载解析XML文件,存到Document中
      • 读取Document,处理为BeanDefinition
    • 第11步根据Bedifinition中对Bean的定义,将bean new出来放在IOC容器中。
      • finishBeanFactoryInitialization()
      • preInstantiateSingletons(),判断抽象、单例、懒加载,FactoryBean。
      • getBean()
      • doGetBean
        • creatBean
        • doCreatBean
          • creatBeanInstance(),默认使用无参构造函数生成Bean
          • 放入三级缓存,用于解决循环依赖
          • populateBean(),依赖注入(DI),填充属性
          • initislizeBean(),调用初始化方法。(AOP发生在此步骤)
        • DI
        • AOP

spring源码关键点

  • FactoryBean与BeanFactory

    BeanFactory,spring中的顶级接口。FactoryBean是工厂Bean。

  • 三级缓存的理解

    三级缓存扩展性更好。二级缓存可以解决循环依赖。但这意味着Bean在实例化之后就要完成AOP代理。而spring设计之初是通过AnnotationAwareAspectJAutoProxyCreator这个后置处理器在创建Bean的最后一步完成AOP代理。

    • 一级缓存 singletonObjects

      单例bean完成三部曲之后,会添加到一级缓存中。存储的是所有创建好了的单例Bean

    • 二级缓存 earlySingletonObjects

      二级缓存,完成实例化,但是还未进行属性注入及初始化的对象。

    • 三级缓存 singletonFactories

      提前暴露的一个单例工厂,二级缓存中存储的就是从这个工厂中获取到的对象.

  • 循环依赖

    如何产生:类A中有一个属性是B,类B中有一个属性是A。初始化A和B的时候,使用构造函数初始化,new A发现需要先new B,new B 发现要先new A。产生循环依赖。构造函数:A(B b){this.b = b}

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class  A{
    private B b;

    public A(B b){this.b = b;}
    }

    class B{
    private A a;

    public B(A a){this.a = a;}
    }

    如何解决:DI属性注入使用set,而不是构造函数。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    class  A{
    private B b;

    public A(){}

    public void setB(){
    return b;
    }

    public B getB(){
    this.b = b;
    }
    }

    class B{
    private A a;

    public B(){}

    public void setA(){
    return a;
    }

    public A getA(){
    this.a = a;
    }
    }

    生成A和B对象的流程。

    1. new A,放入缓存
    2. 依赖注入,set B
      1. new B,放入缓存
      2. 依赖注入,setA,从缓存中取出A,完成setA
    3. 从缓存拿出B,完成setB