1、bean的生命周期底层原理

2、依赖注入底层原理

3、初始化底层原理

如图AnnotationConfigApplicationContext和ClassPathXmlApplicationContext都能获取到对象,它们底层大部分都是共同的,前者基于注解,在新版的Spring MVC和Spring Boot的底层主要用的都是AnnotationConfigApplicationContext,后者基于xml配置文件,而AppConfig.class和spring.xml一样,可以配置扫描路径,定义各种bean

bean的生命周期过程大致如下:

UserService.class==>无参构造方法==>对象==>依赖注入(属性注入)==>初始化前(加了@PostConstruct注解)==>初始化(实现InitializingBean接口)==>初始化后(AOP)==>bean

(利用该类的构造方法来实例化得到一个对象,如果一个类有多个构造方法,spring会进行推断构造方法进行选择;

得到对象之后spring会根据定义的属性上有@Autowired的注解的进行依赖注入;

之后spring会判断该对象是否实现了BeanNameAware接口、BeanClassLoaderAware接口、BeanFactoryAware接口,如果实现了,就表示该对象必须实现该对象中所定义的setBeanName()、setBeanClassLoader()、setBeanFactory()方法,spring会传入对应的参数进行回调;

这时spring会判断该对象的某个方法上是否存在@PostConstruct注解,如存在会在此时调用此方法;

此时,spring会判断该对象是否实现InitializingBean接口,如实现会调用该对象重写的afterPropertiesSet()方法;

最后spring判断当前对象需不需要进行aop,如不需要bean创建完毕,如果需要,进行动态代理并生成一个对象作为bean)

4、推断构造方法底层原理

spring要生成某个bean时,会分成几种情况:

一、如果该类存在一个无参的构造方法,spring就会用这个无参的构造方法

二、如果该类有多个构造方法,并且有默认的构造方法,spring会用默认的构造方法创建对象;如果构造方法加了@Autowired注解那就表示spring会使用这个构造方法创建对象

三、如果该类只存在一个有参的构造方法,那么这个参数必须要存在spring的bean的容器中存在,如果通过类型找到了多个,再通过bean的名称确定唯一一个,最后如果还没有找到会报错

5、aop底层原理

spring在创建bean的最后一步会进行判断该对象是否需要进行aop,找出所有的切面bean,遍历每个切面的方法是否写了@Before、@After、Pointcut等注解,获取到表达式进行匹配,如果匹配到则需要进行aop

aop是基于cjlib的代理,生成被代理类的代理对象,代理类会重写父类的方法,代理类中会有一个target属性,这个属性是经过推断构造器方法实例化出来的对象,进行了依赖注入、初始化等步骤的对象,执行test方法是由target属性来执行的,代理类会根据切面类中定义的方法上的@Before、@After、Pointcut等注解执行,具体如下图显示:

代码是这样的,由一个UserService类的属性OrderService查看开启aop后得到的UserService对象如何调用test()方法

开启aop

配置切面类

下图可以看到代理对象的orderService属性是没有值的,而里面的target属性是有值的,并且target的orderService属性也有值

下面进入到UserService类,可以看到this是target属性,由此可见调用test()方法是经过依赖注入初始化的普通对象

最后打印如下图:

6、spring事务底层原理

spring会查找在某个类的方法上加了@Transactional,spring就会开启事务,而这个时候生成的这个类就是代理对象,spring事务的代理对象执行某个方法时的步骤:

判断执行的方法是否加了@Transactional,如果加了就会使用TransactionMananger事务管理器新建一个数据库连接,修改autocommit为false,使用代理对象的target属性调用业务方法,如果有异常就回滚,没有就commit,下面代码来演示各种情况:

一、@Configuration注解

如下图:开启spring事务管理器,用userService调用test()方法执行插入sql并且抛出异常,最后是能插入数据到数据库的,原因是没有加@Configuration注解,如果加了AppConfig作为一个代理对象,下面获取dataSource的bean的时候spring会找是否有dataSource这个bean如果有则使用这个,这就保证了事务管理器和jdbcTemplate持有的连接是同一个,这就是因为没有加@Configuration事务会失效的原因,因为它们持有的是不同的连接

二、同一个类下的事务失效

下图表示如果已经存在一个事务会抛出异常,而上图没有抛出异常,原因是调用test1()方法的是普通对象,不是代理对象,spring并不会进行事务管理的控制,所以test1()方法的事务失效,加了等于白加

如下图自己注入自己,而调用的方法上又加了@Transactional注解,所以获取到的是UserService的代理对象,会进行事务管控,而普通对象就不会

在spring初始化bean的过程中,会将scope为singleton的初始化到一个map中,这个map它的key是beanName,value是bean对象,那么为什么要根据类型去找?平时在开发过程中可能复制过来名字是一样的,拿到的是其他类,这个时候是不能用的,所以需要先通过类型去找,如果找到了多个再根据名字去找。

普通对象到所谓的bean就像人的一生,去时少年身,归来已白头!

Spring底层核心原理解析相关推荐

  1. Spring源码学习(一)--Spring底层核心原理解析

    目录 Spring中是如何创建一个对象? Bean的创建过程 推断构造方法 AOP大致流程 Spring事务 最近在跟视频学习spring源码,将每节课记录下来,以后好来复习. 首先把Spring中核 ...

  2. 【Spring】Spring底层核心原理解析

    本文内容索引: 1.Bean的生命周期底层原理 2.依赖注入底层原理 3.初始化底层原理 4.推断构造方法底层原理 5.AOP底层原理 6.Spring事务底层原理 ​但都只是大致流程,后续会针对每个 ...

  3. Spring底层核心原理

    Spring底层整体了解 Bean的生命周期底层原理 依赖注入底层原理 初始化底层原理 推断构造底层原理 AOP底层原理 Spring事务底层原理 Spring是如何创建一个对象的 Annotatio ...

  4. Spring框架(一) 底层核心原理解析

    感兴趣的话大家可以关注一下公众号 : 猿人刘先生 , 欢迎大家一起学习 , 一起进步 , 一起来交流吧! 说明 本系列文章以spring-framework-5.3.10为例 , 本篇文章的目的就是使 ...

  5. Spring学习篇底层核心原理解析

    说明 本系列文章以spring-framework-5.3.10为例 ,本篇文章的目的就是使各位读者能在使用Spring的基础上对Spring的一些比较核心的内容有一个大概的认识,并不是特别全面,会在 ...

  6. Spring Boot 核心原理与源码解析 - 目录

    准备重新写 SpringBoot 配置文件解析原理 , 先在这里把要写的内容记下来 Spring Boot 核心原理与源码解析 - 目录 1\何时解析\如何解析 application.propert ...

  7. Spring IOC核心原理分析

    学习过Spring框架的人一定都会听过Spring的IoC(控制反转) .DI(依赖注入)这两个概念,对于初学Spring的人来说,总觉得IoC .DI这两个概念是模糊不清的,是很难理解的,本文系统分 ...

  8. Spring的核心模块解析

    转载自 Spring的核心模块解析 Spring框架是一个轻量级的集成式开发框架,可以和任何一种框架集成在一起使用,可以说是一个大的全家桶.Spring从1.x发展到现在的5.x可以说是越来越强大,下 ...

  9. spring源码分析01-(前期准备)spring核心原理解析和手写简易spring

    1.本文主要介绍内容 本文会把Spring中核心知识点大概解释下.可以对Spring的底层有一个整体的大致了解.主要内容包括: 手写简易spring框架,帮助更好理解spring. 代码点击链接自取 ...

  10. Spring Framework 核心原理与源码解析-大纲

    读Spring Framework的源码的目的是什么? Spring源码阅读的难度在于其呢内容庞大,并不是里面有很复杂的算法,需要高智商才能理解.所以你搞懂了Spring的源码并不能说明你有多聪明,但 ...

最新文章

  1. Centos的网络配置命令和文件
  2. python更新pip失败-新手求助, python 升级 pip 失败
  3. html5重新加载页面,使用AngularJSHTML 5模式重新加载页面会产生错误的GET请求
  4. Mr. Main and Windmills 模拟,计算几何(昆明)
  5. 项目经理的个人体会、经验总结
  6. C语言 | 基于51单片机实现MPU6050的卡尔曼滤波算法(代码类1)
  7. 【论文解读】打破常规,逆残差模块超强改进,新一代移动端模型MobileNeXt来了!精度速度双超MobileNetV2...
  8. 获取界面url_PHP调用百度地图接口,根据IP地址获取地区
  9. Ubuntu如何安装secureCRT
  10. python 持续集成工具_持续集成工具: Jenkins学习
  11. JavaScript 函数(作用域以及闭包)
  12. jquery 获取索引值在一定范围的列表
  13. 渲染器跑分_碾压图灵43!NVIDIA安培第一个跑分震撼出炉
  14. python函数参数用法_Python:函数参数类型及其用法
  15. 微信小程序中使用iconfont作为图标库
  16. rpg存档修改网站_Switch上国宝级欧美版RPG游戏推荐
  17. HTML期末大作业-仿小米商城官网首页模板(HTML+CSS+JavaScript)
  18. 高薪的软件测试工程师要掌握哪些专业技能?
  19. Win 7 配置FTP权限
  20. 基于Python的作业自动批改系统

热门文章

  1. 贝叶斯定理的通俗理解
  2. lnmp 一键安装详解
  3. Redis的集群原理
  4. 扩展欧几里得算法 思想及模板代码
  5. 简单计算机病毒黑屏,电脑被木马病毒侵袭,黑屏了怎么处理
  6. 【超级鼠标键盘锁】之HOOK钩子屏蔽鼠标和Ctrl+Alt+Del、Win+L之外的按键
  7. centos7下定时重启tomcat
  8. .NET(c#) 移动APP开发平台之Smobiler开发
  9. python局域网传输文件
  10. kali教程--破解wifi密码