spring源码学习

这篇具有很好参考价值的文章主要介绍了spring源码学习。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1.xmlBeanFactory对defaultListableBeanFactory类进行扩展,主要用于从XML文档中获取BeanDefinition,对于注册及获取bean都是使用从父类DefaultListableBeanFactory继承的方法去实现。
xmlBeanFactory 主要是使用reader属性对资源文件进行读取和注册。
2.循环依赖。创建bean,核心方法
getBean → doGetBean → createBean → doCreateBean → createBeanInstance → populateBean
3.BeanDefinitionReader获取资源文件,封装成BeanDefinition,通过BeanDefinitionRegistry将其注册起来,保存到BeanDefinitionMap中。BeanFactory根据bean定义信息,通过反射实例化bean。
4.FactoryBean,灵活创建bean。调用getObject方法,才会生成bean,但没有严格的bean生命周期流程
5.spring中有两种bean:容器bean(比如BFPP)、自定义bean
6.FactoryBean和BeanFactory

  • FactoryBean本身也是一个bean对象,是一个小工厂,能够生产另外的Bean。“&”+ beanName就是FactoryBean对象。
  • BeanFactory是spring的根接口,是大工厂,生成各种各样的bean。普通bean对象没有"&"
    spring源码学习

7.PostProcessor

  • 后置处理器、增强器。有了它,我们可以在各个过程中,合理应用它,对bean定义信息进行扩展、修改
  • 针对beanFactory的后置处理器
    • BeanFactoryPostProcessor
    • BeanDefinitionRegistryPostProcessor 继承 BeanFactoryPostProcessor
  • 针对bean的后置处理器
    • BeanPostProcessor
    • InstantiationAwareBeanPostProcessor 继承 BeanPostProcessor

8.循环依赖-三级缓存

  • 只用二级缓存会将AOP中创建代理对象的时机提前,设计之初是让bean在生命周期的最后一步完成代理而不是在实例化后就马上完成
  • 循环依赖发生时提前代理,没有循环依赖代理方式不变,依然是初始化后代理
  • 如果只有1个缓存,能解决循环依赖吗?
  • 如果只有2个缓存,能解决循环依赖吗?
    • 可以,但是有aop的话,会违反设计理念,提前创建代理对象
  • 为什么使用3级缓存之后,就可以解决带aop的循环引用
    • aop是在实例化后、属性赋值(被调用)时,判断是否需要生成代理对象的。但是我们没有办法知道对象什么时候要被调用,所以用第3级缓存,保存lambda表达式,当对象被调用时,执行lambda表达式,判断是否返回代理对象
  • 为什么spring不能解决构造方法的循环依赖
    • 在Bean调用构造器实例化之前,一二三级缓存并没有Bean的任何相关信息,在实例化之后才放入三级缓存中,因此当getBean的时候缓存并没有命中,这样就抛出了循环依赖的异常了。
  • 为什么多例Bean不能解决循环依赖?
    • 我们的bean是单例的,而且是字段注入(setter注入)的,单例意味着只需要创建一次对象,后面就可以从缓存中取出来,字段注入,意味着我们无需调用构造方法进行注入。
    • 如果是原型bean,那么就意味着每次都要去创建对象,无法利用缓存;
    • 如果是构造方法注入,那么就意味着需要调用构造方法注入,也无法利用缓存。
  • 三级缓存介绍
    • 一级缓存的作用:存放可用的成品bean;
    • 二级缓存的作用:为了将成熟Bean和纯净Bean分离(未注入属性),避免多线程下读取到不完整的Bean;存放半成品bean,半成品bean即已经调用完构造但是还没有注入属性和初始化;
    • 三级缓存的作用:用来生产半成品的bean,与getbean方法解耦,能解决aop增强下的循环依赖;存放函数接口/钩子函数,函数接口实现创建动态代理调用BeanPostProcessor,即其要加强的aop处理(为了避免重复创建,调用会返回动态代理对象或者原实例,再存储在二级缓存);

真正的解决循环依赖是靠二级缓存,不用三级缓存也可以解决循环依赖,但这样就造成了在实例化后就立马完成代理,违背了最后一步完成代理的原则;
在创建bean的时候,在哪里通过什么方式创建了动态代理:通过BeanPostProcessor创建动态代理,在初始化之后或在出现循环依赖时实例化之后(实例化 -> 属性注入 -> 初始化)
发生循环依赖会用到二级缓存,普通依赖过程只用到一三级缓存

9.配置类加@Configuration 和不加的区别
@Bean中被依赖的bean不会被重复加载
@Configuration为Full配置类,经过了enhance增强处理,所有@Bean方法会被BeanMethodInterceptor拦截,根据方法名获取单例,而不是重复加载

10.Spring是怎样避免读取到不完整的Bean

防止多线程下Spring读取到不完整Bean加了两把锁
一把锁放在getSingleton()方法三级缓存,第二个线程阻塞直到第一个线程把二三级缓存删除完;
一把锁放在getSingleton(,)方法,先从单例池再拿一遍单例对象(double check防重复创建单例bean)
怎么样可以在所有Bean创建完后做扩展代码?
ContextRefreshedEvent/SmartInitializingSingleton

11.接口

  • BeanFactory

  • Aware

  • BeanDefition

  • BeanDefitionRegistry

    • 注册bean定义信息,对bean定义信息进行增删改查
  • BeanDefitionReader:bean定义信息读取器,解析xml、注解,转化为BeanDefinition,添加到BeanDefinitionMap中

  • BeanFactoryProcessor:bean工厂后置处理器,可以修改bean定义信息

  • BeanPostProcessor: bean后置处理器

  • Environment

    • StandardEnviroment :当完成整个程序的加载之后,会运行很多系统的一些属性值,添加到当前对象。后续程序运行的时候,直接从当前对象获取,而不需要每次都去读取
      • System.getEnv()
      • System.getProperties()
  • FactoryBean

    BeanFactory和factoryBean的区别都是用来创建对象的。当使用BeanFactory时,必须要遵循完整的创建过程。这个过程由spring管理。factoryBean只需要调用getObject就可以返回具体对象,整个对象创建过程由用户自己控制,更加灵活

    • isSingleton
    • getObject :用来返回具体对象。可以new,也可以反射。核心的点在于进行容器获取对象时,每次创建对象之前,都会提前做当前对象的一个判断
    • getObjectType
    • getBean(“&” + beanName) 就是获取工厂
    • 意义在于,我需要的时候,通过当前工厂里的getObject方法创建,而不需要遵循bean的生命周期

12.spring执行流程

  • ClassPathXmlApplicationContext构造方法
    • 调用父类构造方法,进行相关对象创建,初始化操作,准备好一些需要的集合、对象
    • 设置配置文件路径
    • 调用AbstractApplicationContext#refresh 13个方法
      • prepareRefresh:准备刷新工作
        • 设置开启时间
        • 设置开闭状态
        • initPropertySource 初始化属性资源
        • getEnvironment 获取环境对象
          • 父类构造方法中调用了customizePropertySource——定制化属性资源
        • 创建监听器、需要发布的事件集合,方便做扩展属性
      • obtainFreshBeanFacotry获得一个刷新的bean容器,创建当前工厂对象 DefualtListableBeanFactory,同时加载配置文件到属性值到当前工厂中,最重要的就是beanDefinition
        • refreshBeanFactory:如果有bean工厂,关闭,销毁,产生新的工厂
          • createBeanFactory
            • new DefualtListableBeanFactory
          • customizeBeanFacotry:是否允许被覆盖、是否允许被重写
          • loadBeanDefinitions:因为配置文件是多个的,这个方法有N多个重载的方法。把当前这些配置文件解析,封装成Beandefinition
        • getBeanFactory
      • prepareBeanFactory:给当前bean工厂设置属性值,完成bean工厂的初始化工作
        • 加载beanFactoryPostProcessor
        • 忽略aware接口实现,后面是在invokeAwareMethod中实现的
      • postProcessorFactory:后置处理相关操作,方法是空的(模板方法)
      • invokeBeanFactoryPostProcessor,实例化并且执行所有已经注册的BFPP
      • 准备实例化、初始化所需要的一些类、对象。创建bean
  • 几个重要的实现类
    • HierarchicalBeanFactory 获取父类工厂。在doGetBean方法中需要获取父类工厂
    • ListableBeanFactory,枚举所有bean实例
    • ConfigurableBeanFactory
    • DefaultListableBeanFactory
  • RootBeanDefinition
  • GenericBeanDefinition
  • getMergedBeanDefinition方法
    spring源码学习
    源码图(调用关系)
    spring源码学习

思维导图链接

spring执行流程总结

1.入口refresh();
2.实例化、初始化bean工厂,加载配置信息、资源、扫描包路径、注解,生成BeanDefinition对象,注册到BeanDefinitionMap中
3.注册BeanPostProcessor,执行BeanFactoryPostProcessor;
4.实例化bean(bean的生命周期)文章来源地址https://www.toymoban.com/news/detail-463160.html

  • 实例化bean对象
  • 属性注入
  • 初始化
    • 回调aware接口
    • 执行BeanPostBeforeProcessor
    • 如果实现了 InitializingBean接口,执行afterPropertiesSet方法
    • 如果有initMethod方法,就执行
    • 执行BeanPostAfterProcessor
  • 使用bean
  • 销毁bean

到了这里,关于spring源码学习的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Spring Boot 源码学习】HttpEncodingAutoConfiguration 详解

    Spring Boot 源码学习系列 前面的博文,我们从源码角度介绍了自动装配流程。虽然带大家从整体上有了清晰的认识,但是我们还不能熟练地运用。本篇就以 Spring Boot 内置的 http 编码功能为例,来带大家分析一下 HttpEncodingAutoConfiguration 的整个自动配置的过程。 在开始本篇的内容

    2024年02月08日
    浏览(37)
  • 【Spring Boot 源码学习】RedisAutoConfiguration 详解

    《Spring Boot 源码学习系列》 上篇博文, Huazie 带大家从源码角度分析了 Spring Boot 内置的 http 编码功能,进一步熟悉了自动配置的装配流程。本篇趁热打铁,继续带大家分析 Spring Boot 内置的有关 Redis 的自动配置类【 RedisAutoConfiguration 】。 在开始本篇的内容介绍之前,我们先来

    2024年02月07日
    浏览(39)
  • 【Spring Boot 源码学习】BootstrapRegistry 详解

    《Spring Boot 源码学习系列》 前面的博文《BootstrapRegistryInitializer 详解》,Huazie 带大家一起详细分析了 Spring Boot 启动时加载并初始化 BootstrapRegistryInitializer 及其相关的类的逻辑。其中有个 BootstrapRegistry 接口只是简单提及,本篇就详细分析一下 BootstrapRegistry 接口,这对于我们后

    2024年02月20日
    浏览(36)
  • 【Spring Boot 源码学习】走近 AutoConfigurationImportSelector

    《Spring Boot 源码学习系列》 上篇博文我们了解了 @EnableAutoConfiguration 注解,其中真正实现自动配置功能的核心实现者 AutoConfigurationImportSelector 还没有详细说明,本篇将从它的源码入手来重点介绍。 在介绍 AutoConfigurationImportSelector 之前,有必要了解下它所实现的 ImportSelector 接

    2024年02月12日
    浏览(29)
  • 【Spring Boot 源码学习】JedisConnectionConfiguration 详解

    《Spring Boot 源码学习系列》 上篇博文, Huazie 带大家从源码角度分析了 Spring Boot 内置的有关 Redis 的自动配置类【 RedisAutoConfiguration 】,其中有关 LettuceConnectionConfiguration 和 JedisConnectionConfiguration 这两个用于配置 Redis 连接的具体实现还未介绍。本篇就以我们常用的 Jedis 实现

    2024年02月05日
    浏览(39)
  • 【Spring Boot 源码学习】OnWebApplicationCondition 详解

    《Spring Boot 源码学习系列》 上篇博文带大家从 Spring Boot 源码深入详解了 OnBeanCondition ,那本篇也同样从源码入手,带大家深入了解 OnWebApplicationCondition 的过滤匹配实现。 在开始本篇的内容介绍之前,我们先来看看往期的系列文章【有需要的朋友,欢迎关注系列专栏】: Spr

    2024年02月08日
    浏览(38)
  • 【Spring Boot 源码学习】初识 SpringApplication

    《Spring Boot 源码学习系列》 往期的博文, Huazie 围绕 Spring Boot 的核心功能,带大家从总整体上了解 Spring Boot 自动配置的原理以及自动配置核心组件的运作过程。这些内容大家需要重点关注,只有了解这些基础的组件和功能,我们在后续集成其他三方类库的 Starters 时,才能够

    2024年02月05日
    浏览(39)
  • 【Spring Boot 源码学习】深入 FilteringSpringBootCondition

    Spring Boot 源码学习系列 前两篇博文笔者带大家从源码深入了解了 Spring Boot 的自动装配流程,其中自动配置过滤的实现由于篇幅限制,还未深入分析。 那么从本篇开始,Huazie 就带大家走近 AutoConfigurationImportFilter ,一起从源码解析 FilteringSpringBootCondition 、 OnBeanCondition 、 OnCl

    2024年02月09日
    浏览(40)
  • 【Spring Boot 源码学习】@Conditional 条件注解

    《Spring Boot 源码学习系列》 前面的博文,Huazie 带大家从 Spring Boot 源码深入了解了自动配置类的读取和筛选的过程,然后又详解了 OnClassCondition 、 OnBeanCondition 、 OnWebApplicationCondition 这三个自动配置过滤匹配子类实现。 在上述的博文中,我们其实已经初步涉及到了像 @Conditi

    2024年02月07日
    浏览(41)
  • 【Spring Boot 源码学习】SpringApplication 的定制化介绍

    《Spring Boot 源码学习系列》 前面的博文, Huazie 带大家从 Spring Boot 的启动类 SpringApplication 上入手,了解了 SpringApplication 的实例化过程。这实例化构造过程中包含了各种初始化的操作,都是 Spring Boot 默认配置的。如果我们需要定制化配置, SpringApplication 也提供了相关的入口

    2024年01月25日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包