一、模块划分

  • Core Container

    • Core  核心工具类

    • Beans 包含配置文件、创建和管理bean和IOC用到的类

    • Context 构建在Core和Beans模块基础上,添加国际化,事件传播,资源加载等,ApplicationContext接口是关键

    • Expression Language模块是表达式语言EL的包

  • Data Access/Integration

    • JDBC 提供JDBC的抽象层

    • ORM 提供流行ORM框架的交互封装

    • OXM Object/xml映射的抽象

    • JMS 制造和消费消息特性

    • Transaction 支持编程和声明性事务管理

  • Web

    • Web  基础的面向Web,比如多文件上传,servlet listeners初始化IOC容器,面向web的应用上下文

    • Web-Servlet 包含SpringMVC的实现

    • Web-Struts 对Struts的支持

    • Web-porlet 对Portlet的支持

  • AOP

    • Aspects 对AspectJ的支持

    • Instrumentation 对class instrumentation和classloader实现

  • Test

二、容器的类关系

    

重要的几个

  • DefaultListableBeanFactory :spring加载bean的默认实现

  • XmlBeanDefinitionReader:用来读xml文件的

  • XmlBeanFactory: 常用这个读xml来建容器

三、ApplicationContext初始化流程

  1. ClassPathXmlApplicationContext为入口构造方法中有个refresh()方法用来初始化Spring 

    1. refresh运行的大致流程: 

    2. prepareRefresh()——————————初始化准备和验证系统属性环境变量啥的

    3. ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();  ——————————初始化BeanFactory

    4. prepareBeanFactorybeanFactory()——————————填充BeanFactory

    5. postProcessBeanFactory(beanFactory)​——————————额外处理子类覆盖方法

    6. invokeBeanFactoryPostProcessors(beanFactory);——————————激活各Factory处理器

    7. registerBeanPostProcessors(beanFactory);———————————–注册bean处理器

    8. initMessageSource();——————————————————-初始化Message,国际化

    9. initApplicationEventMulticaster();—————————————–初始化应用消息广播

    10. onRefresh();—————————————————————留给子类初始化其它Bean

    11. registerListeners();——————————————————bean中查找Listener,注册到广播器

    12. beanFactory.preInstantiateSingletons();————————————

    13. publishEvent(new ContextRefreshedEvent(this));—————————–

  2. 初始化准备和验证系统属性环境变量

  3. 解析XML并且初始化工厂类,BeanFactory工厂提供了获得bean实例的能力,通过AbstractApplicationContext类中的obtainFreshBeanFactory方法调用refreshBeanFactory实例化一个默认的BeanFactory工厂DefaultListableBeanFactory,然后调用loadBeanDefinitions装载配置文件,解析配置文件(XmlBeanDefinitionReader)时会创建BeanDefinition并且放到容器DefaultListableBeanFactory中去。

    1. 判断hasBeanFactory则卸载Bean并closeBeanFactory

    2. 创建DefaultListableBeanFactory​

    3. 为它指定序列化id

    4. customizeBeanFactory,定制BeanFactory

      1. 在这里设置@Qualifier和@Autowired的解析器,beanFactory.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver())

        1. byType注入时,解析autowire会调用getAutowireCandidateResolver().getSuggestedValue(descriptor),上面的解析器就实现了getSuggestedValue

    5. 加载BeanDefinition

    6. 全局变量jiluBeanFactory实例​

  4. 填充BeanFactory,比如@Qualifer和@Autowired在这里增加的支持

    1. 设置beanFactory的classLoader为当前Context的classLoader

    2. SPEL支持​

    3. 属性编辑器支持

      1. 比如注入的时候Date无法被识别

    4. 添加BeanPostProcessor

      1. 添加ApplicationContextAwareProcessor处理器,beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));

    5. 增加一些内置类信息注入,设置依赖功能可忽略的接口,注册一些固定依赖

    6. 增加AspectJ支持​

  5. 子类用的​

  6. 执行工厂后置处理器,这时会查找所有BeanFactory(DefaultListableBeanFactory)工厂中的bean找出所有BeanFactoryPostProcessor实现类bean,并且调用方法postProcessBeanDefinitionRegistry,这个方法可以在bean实例化之前修改配置信息(比如变量值) 

    1. 典型的BeanFactoryPostProcessor就是PropertyPlaceHolderConfigurer,bean描述文件中${}这昂的变量引用,就靠它

  7. 注册后置处理器,这时会查找所有BeanFactory(DefaultListableBeanFactory)工厂中的bean找出所有BeanPostProcessor实现类bean,并且把他们注册到BeanFactory容器中去,和第3种工厂后置处理器的区别是BeanFactoryPostProcessor会立即调用,而BeanPostProcessor注册到BeanFactory中 

    1. PS:用户自定义BeanPostProcessor

  8. 默认注册一个bean名称为messageSource的bean用于国际化处理,这里Spring自带很多种实现,这个方法会先查找BeanFactory中的bean是否有messageSource名称的bean如果没有给一个默认的实现DelegatingMessageSource  PS:用户可以自定义名称为messageSource的bean,只需要实现MessageSource即可

  9. Spring事件体系包括三个组件:事件,事件监听器,事件广播器。这里是初始化事件广播器,如果用户有自定义applicationEventMulticaster名称的bean并且实现ApplicationEventMulticaster则不需要处理,如果没有就给一个默认的实现SimpleApplicationEventMulticaster 

    1. 用户可以自定义名称applicationEventMulticaster并且实现ApplicationEventMulticaster接口的bean

    2. 没有自定义就用默认的,initApplicationEventMulticaster​方法初始化

    3. 实际接收事件被调用的方法​是multicastEvent(ApplicationEvent event)

  10. 子类用的

  11. Spring事件体系包括三个组件:事件,事件监听器,事件广播器。这里是事件监听器,上下文会在BeanFactory找到所有实现ApplicationListener的bean然后添加到事件广播器ApplicationEventMulticaster中去

    1. 硬编码注册或者配置文件注册,都是getApplicationEventMulticaster.addApplicationListener(listener)

  12. 初始化单例的bean,实例化BeanFactory中所有的bean,(Spring配置的是单例设置scope=”prototype”可以配置多例模式)

  13. 发布上下文刷新事件,事件广播器负责将些事件广播到每个注册的事件监听器中,容器启动完成

四、bean加载流程

  • 转换对应beanName,transformedBeanName

    • 可能是别名alias,也可能是FactoryBean带&的bean,去掉&

  • 尝试从缓存中加载单例, getSingleton

    • 见五

  • 实例化,getObjectForBeanInstance

    • 如果缓存中得到bean的原始状态则需要实例化,因为缓存中可能是最原始的bean状态,比如工厂bean,需要的是factory-method中的bean

  • 原型模式循环依赖检查,isPrototypeCurrentlyInCreation

    • 原型模式有循环依赖直接抛异常

  • 检查parentBeanFactory

    • 如果父工厂不为null,且当前的beanName不在XML配置文件中,就只能调用父工厂的getBean找

    • 为啥要用工厂

  • 存储xml的GernericBeanDefinition转为RootBeanDefinition, getMergedLocalBeanDefinition和checkMergedBeanDefinition

    • 如果BeanName是子Bean会合并父类相关属性

  • 寻找依赖,getDependsON

    • 先初始化依赖,getBean然后registerDependentBean

  • 根据scope创建bean

    • 无论单例、原型还是request都要调createBean和getObjectForBeanInstance

    • getSingleton(beanName,new ObjectFactory)

      • 为啥要Factory呢

    • beforePrototypeCreation,然后create,然后afterPrototypeCreation

    • 其它的根据scope对象整

  • 类型转换,根据requiredType转换

五、缓存中获取单例bean,getSingleton方法

  • 参数为beanName和是否允许早期依赖的标记

  • 检查缓存this.singletonObjects中是否有

  • 为空,锁定this.singletonObjects

  • 检查this.earlySingletonObjects中是否有

  • 为空,且标识为true,从this.singletionFactories中获取singletionFactory

    • 为啥需要factory。。。。。

  • 如果不为null,调用singletionFactory.getObject(),记录在earlySingletonObjects中,从singletionFactories中删除

六、直接获取单例,也是getSingleton方法

  • 参数是beanName和singletonFactory

  • 加锁this.singletonObjects

  • 缓存中检查是否有bean

  • 为空,beforeSingletonCreation记录beanName正在加载的状态,记载this.singletonsCurrentlyInCreation中,用于检查循环依赖

  • singletonFactory.getObject()初始化bean

  • 调用加载单例后的处理方法

  • afterSingletonCreation从加载状态中移除bean

  • addSingleton,加锁this.singletonObjects,写入singletonObjects,从early和工厂缓存中删除

    • 为啥又加锁一次this.singletonObjects

  • 返回处理结果

七、singletonFactory中的getObject与createBean

  • 上面也看到了传给getSingleton的是一个匿名singletonFactory,实现了个getObject,中间有createBean方法

  • 根据class属性或者className解析Class

  • 标记验证override

    • 这块再看看,啥堆methodOverrides动态生成代理了就

  • 应用初始化前的后处理器,解析bean是否存在短路操作

    • 短路?

  • 创建bean,doCreateBean

    • 如果是单例先清除缓存

    • 实例化bean,beanDefinition转换为BeanWrapper, createBeansInstance

      • 如果存在工厂方法(RootBeanDefinition存在factoryMethodName属性或者说配置文件中有factory-method)则使用工厂方法初始化

      • 根据参数锁定构造函数

        • 根据指定的参数获取

        • 不行从缓存中获取

        • 不行从配置文件中获取

      • 都不存在则默认初始化

      • 实例化策略非简单的反射,判断如果beanDefinition.getMethodOverrides为空就反射,没有就通过动态代理增强

    • 枷锁实例的postProcessingLock,应用MergedBeanDefinitionPostPrecessor

      • bean合并后的处理,Autowired主节通过此方法实现类型的预解析

    • 处理依赖

      • 当单例且允许循环依赖且当前bean在创建中时,earlySingletonExposure为true

      • addSingletonFactory,参数beanName和新 ObjectFactory工厂

        • 工厂中getObject只有return getEarlyBeanReference,AOP就是在这里将advice动态织入bean中

    • 属性注入bean

      • InstantiationAwareBeanPostProcessor处理器的postProcessAfterInstantiation方法应用

        • 控制是否继续属性填充

      • 根据byName/byType,提取依赖的bean

        • autowireByName,递归getBean,注册依赖

        • autowireByType,哇这个超复杂。。。引申一个注解Autowired到List上会怎样的问题

      • InstantiationAwareBeanPostProcessor处理器的postProcessPropertyValues方法应

      • 将属性填充到BeanWarapper

    • 调用initializeBean方法,比如init-method

    • 循环依赖检查

    • 如果配置了destory-method,注册DisposableBean

八、设计模式

a. 简单工厂:并不属于23种设计模式,BeanFactory就是传入一个标识来获取bean对象

  • 即静态方法模式,一个工厂一个产品接口多产品,工厂根据传入的name输出对应product

  • 实例的创建与使用分开,解耦client与具体产品(client依赖工厂和product接口);实例化的工作统一在工厂中,便于全局唯一

  • 违反开闭,加产品得改代码;工厂类出问题整体都受影响;静态方法不被重写工厂们无法有继承关系

b. 工厂方法:FacotyBean就是工厂方法模式

  • 一个工厂接口多工厂一个产品接口多产品,一一对应

  • 符合开闭,加产品直接加工厂和产品,不修改工厂代码;符合单一职责;可形成继承

  • 工厂和产品成对增加了复杂度和开销;一个工厂一个产品;系统抽象性增加

c. 单例模式:单例Bean,不过这仅仅是提供了全局访问的BeanFactory,并没有从构造器级别去保证只有一个单例

d. 适配器模式:AOP中使用Advice(通知)来增强被代理类的功能,BeforeAdvice、AfterReturningAdvice、ThreowSadvice每个Advice有对应的拦截器MethodBeforeAdviceInterceptor、AfterReturningAdviceInterceptor、ThrowsAdviceInterceptor,Spring通过适配者讲Advice封装成Interceptor

e. 装饰器模式:动态的给对象添加额外的职责

  • spring中名字带Wrapper和Decorator的类,比如BeanDefinition变BeanWarrper(我猜的)

  • 代理偏重自己不知道的流程,装饰器偏重对象

  • 开闭原则的体现,耦合低,扩展灵活,防止继承爆炸

  • 缺点:过多装饰一个类,增加复杂度

f. 代理模式:AOP

g. 观察者模式:ApplicationListener,如果容器中有一个ApplicationListener Bean,每当ApplicationContext发布ApplicationEvent时,ApplicationListener Bean将自动被触发

h. 策略模式:实例化对象时用到,根据创建对象的三个分支( 工厂方法、有参构造方法、无参构造方法 )

  • createBeanInstance的时候

i. 模板方法模式:JdbcTemplate,事务Template

      

九、bean生命周期

spring源码个人总结(待完成)-LMLPHP

十、

09-28 06:53