—————–【B站孙帅suns的Spring源码第一集总结】
对Spring生态的认知
1、对Spring的认知
-
1、时至今日我们认为Spring可能就是 解决方案、技术栈、全家桶
-
2、首当其冲的单纯就是Spring框架,做web开发又衍生出来了SpringMVC,后续为了能够更加快速的开发引入了SpringBoot,有了SpringBoot,我们可能基于SpringBoot要开发微服务,于是有了SpringCloud,
-
3、针对于Spring还有一些附属的框架
-
比如说我想做安全验证,SpringSecurity
-
比如说我想做批处理,SpringBatch
-
持久化框架,SpringData衍生出来了很多内容
- Redis分支
- JPA分支
- MongoDB分支
- Hadoop分支
-
如果我们想做社交登录,可能还需要SpringSocail
-
包括Spring管理分布式的叫SpringSession
-
整个的 我们可以认为这是一套完整的基于Spring的解决方案,这一大套东西,在现在基本在整个java开发当中,标配的是
-
后续衍生出
-
-
4、但是不管怎么样,今天整个spring的生态能做到这么大,都源自于spring框架自身的很多优秀特点,
- 比如基础课程中,给大家反复强调过的两大特性 IOC、AOP,其实你会发现在整个生态当中基本上都会有这两个核心技术的影子,来保证后续进行更复杂的生态构建。
2、对SpringBoot的认知
- 5、在十几年前,作为我那个时候的开发者来说,当时只有Spring,同学们肯定会有疑问我们当时没有用MVC吗,用,用的是最流行的struts1、后续又衍生出了struts2包括springmvc,所以我那时候开发只有spring,但是当我掌握spring之后,这些都相当的容易了,为什么?作为SpringMVC来讲 它就是两个东西的堆砌,一个是Spring框架,一个是MVC,对于Spring来讲我已经掌握了,作为MVC来讲不管它是什么样的框架,都会有MVC的核心内容在里面,都会有收集客户端的请求数据哇,进行全局性的异常处理,标签库的展示,有些MVC数据的传导等等,所以当过渡到SpringMVC的时候相对来说比较容易了。
- 实际上到了今天大家在做开发的时候,我们所使用的技术栈,还是以 Spring、SpringMVC这两个为核心
- 有同学说我们现在不是已经开始用SpringBoot了吗,那么SpringBoot到底的真正价值在哪?
- 在SpringBoot这块一定要让大家注意的是,作为我们说的SpringBoot来讲,不要把它妖魔化,觉得SpringBoot很神奇,SpringBoot很厉害,其实不是这样的,SpringBoot的真正价值是 简化Spring和SpringMVC的开发,这才是它的核心。
- 所以我们常说 作为SpirngBoot来讲,它本质上没有什么新的东西,只要spring和springMVC的基础足够扎实,你学spring在我看来就是分分钟的事儿,他就是对Spirng和SpringMVC的简化
- 比如说后我们举个例子,它简化到哪了,我们现在都是基于maven进行构建应用,导入依赖,这是相对来说比较繁琐的,虽然引入了maven,但是大量的jar包还得自己去找,作为SpringBoot来讲,它就会觉得不需要了,所以就给我们定制了很多starter,更加方便的去导入jar包,只要导入一个starter就会连带性的把相关的jar包引进来,
那除此之外呢?它还干了什么?简化冗余配置,我们说对spring来讲的话,从原始的xml到后续的注解,有了一个简化的过程,但是它还是比较麻烦,甚至很多东西都需要程序员一遍一遍的去配,那怎么办?SpringBoot对这些进行了相应的封装,各种个样的AutoConfig、config来进行相应的封装,这实际上是SpringBoot为我们带来的最核心的两个功能。
所以我们说你前面的这两个技能足够扎实的话,SpringBoot的学习是非常的简单,非常的快速,你也可以很轻易的去上手,而作为我们大家来讲,之所以这块儿会出现问题的原因是 你前期Spring的知识 SpringMVC的知识 你都没有深入到一定的水平,很多东西 都是有的,那最后你到SpringBoot你当成新的功能来学,那当然你就会觉得东西很多了,甚至说你都找不到它的出处。所以说现在实际上很多人在讲SpringBoot,不如说他在讲SpringMVC,因为没有SpringBoot我用SpringMVC也可以基于注解,也可以通过相应的配置bean,来进行设置,所以说这是springBoot
3、SpringBoot的好处
-
当然另外一个SpringBoot给我们带来的好处是,内嵌了tomcat,内嵌的tomcat对于我们来讲,实际上是一个非常重要的特性,内嵌tomcat有两个特别大的好处
-
一个好处是 解决了SpringMVC中父子容器,在SpringBoot中没有人再提父子容器的问题了,这是在SpringMVC开发当中非常重要的一个问题,是需要我们大家解决的。
-
问问大家我们在SpirngMVC开发当中是怎么解决父子容器的问题的呢?能不能回答我,大家的回答太让我寒心了。
-
首先要明白的一个问题是,在SpringMVC开发中同时存在两个Spring工厂
-
springMVC的配置在web.xml当中我们会配置一个
DispatcherServlet 指定dispartcher.xml
-
DispatcherServlet其实就是spring的一个工厂
-
后续还会在web.xml中配置一个listener
ContextLoaderListener
-
ContextLoaderListener本质上也是创建了一个工厂
-
这样你在SpringMVC开发的过程中,实际上是有两个工厂,一个DispatcherServlet【child】一个ContextLoaderListener【root】,两个工厂并存
-
如果不经过任务处理的话,SpringMVC父子容器会带来一个问题,
-
Controller 去获取Service的时候,虽然Service 配置了事务,但是事务没有生效,原因,配置事务的时候是在父工厂配置的,而子工厂此时获得的是子工厂创建的service,这个问题的核心是,你在父工厂创建了service添加了事务
而在子工厂中 创建 了Service,但它没有事务 ,子工厂创建Controller 取的是子工厂的service,这个service是没有事务的。这是开发当中最常见的问题了,那么如何解决呢?- 子工厂不要创建service 去调用 父工厂的service
-
SpringBoot就没有父子容器问题,因为SpringBoot中的Tomcat是内嵌的,不需要外部集合的方式来解决,所以整个SpringBoot中是没有父子容器的。
-
-
第二个好处,一个tomcat是一个进程,而SpringBoot内嵌了Tomcat之后,我们就可以以jar包的形式,启动tomcat运行进程,这样就会产生一个特别有益的效果就是,在整个SpringBoot的开发过程当中,我们可以创建多个tomcat进程。换句话说,可以把一个大的应用 或者就是很多人说的 把单体应用,拆分成若干个独立的进程、独立的服务,都能对外发起请求接受相应。
-
所以这才是SpringBoot给我们带来的实质性内容,除了这些内容 其他的和SpringBoot没有任何关系。
-
正是因为有了SpringBoot能够让我们快速开发,同时内嵌一个Tomcat去运行多个进程,把一个单体应用进行拆分,所以才有了后续的SpringCloud,所以你要知道SpringCloud 为什么今天必须要嫁接SpringBoot,是因为SpringBoot有这些优势。
-
4、如果没有SpringBoot,我们可不可以去做SpringCloud呢?
- 如果没有SpringBoot,我们依旧可以有类似于SpringCloud的方案,但是不是说SpringCloud、SpringCloudAlibaba可以脱离SpringBoot,这些现成的 都不能脱离SpringBoot,因为都是基于SpringBoot来做的,如果没有SpringBoot也绝不会影响到微服务的发展,甚至我们就可以使用Spring、SpringMVC去打造微服务,这个时候就没有SpringCloud了,有的只是Spring、SpringMVC为我们构建了微服务,微服务是一种架构思想,解决了很多分布式问题,而SpringCloud仅仅是微服务的一种实现方案,如果后续没有了SpringBoot,那一样就没有SpringCloud,那我用Spring、SpringMVC一样可以实现微服务,只不过做起来相对比较麻烦,甚至我们还可以脱离java体系,用Go来做微服务,在整个今天所说的云原生架构和微服务的架构来看的话,有两大编程语言,是可以有机的它们和微服务和云原生结合在一起的,一个是我们熟知的java,另外一个就是GO,因为我们所熟知的docker和K8S都是Go开发的,GO天生就亲近它们,GO把Java所谓的网关啊、所谓的路由这些东西 都可以使用 Docker 或者 K8S 或者GO的一些插件来替换,所以说 这些都是无所谓,都是通的,这一块是需要大家注意的。 所以讲这块的目的,想让各位能够了解到的是什么?不管是SpringBoot也好,SpringCloud也好 它们还是停留在了应用层,就是用就可以了,最多就是体会一下它们是怎么封装的,而真正的核心 在整个Spring系列当中 还是要 以Spring和SpringMVC 为重中之重。
- 所以我们整个的课程安排来讲的话,我们接下来的若干次课程,都会以分析Spring这个框架的源码为核心,如果这个框架的源码大家掌握了的话,那我可以很负责任的告诉各位的就是,你们在过渡到SpringMVC 以及过渡到SpringBoot的时候,你们就已经脱离了基本的应用了,那完全可以做到的是对它的内部运行是非常非常了解的,所以我们要花出很大一部分时间去研究源码的实现。
5、SpringBoot与SpringCloud的关系
- 一个tomcat是一个进程,而SpringBoot内嵌了Tomcat之后,我们就可以以jar包的形式,启动tomcat运行进程,这样就会产生一个特别有益的效果就是,在整个SpringBoot的开发过程当中,我们可以创建多个tomcat进程。换句话说,可以把一个大的应用 或者就是很多人说的 把单体应用,拆分成若干个独立的进程、独立的服务,都能对外发起请求接受相应。
- 所以这才是SpringBoot给我们带来的实质性内容,除了这些内容 其他的和SpringBoot没有任何关系。
- 正是因为有了SpringBoot能够让我们快速开发,同时内嵌一个Tomcat去运行多个进程,把一个单体应用进行拆分,所以才有了后续的SpringCloud,所以你要知道SpringCloud 为什么今天必须要嫁接SpringBoot,是因为SpringBoot有这些优势。
6、SpringMVC如何解决父子容器问题?
- 子工厂不要创建service 去调用 父工厂的service
7、SpringMVC父子容器会带来什么问题?
- 如果不经过任务处理的话,SpringMVC父子容器会带来一个问题,
- Controller 去获取Service的时候,虽然Service 配置了事务,但是事务没有生效,原因,配置事务的时候是在父工厂配置的,而子工厂此时获得的是子工厂创建的service,这个问题的核心是,你在父工厂创建了service添加了事务
而在子工厂中 创建 了Service,但它没有事务 ,子工厂创建Controller 取的是子工厂的service,这个service是没有事务的。这是开发当中最常见的问题了
学习源码的认知
1、学习源码认知
1、枯燥,从今天开始就要开始学习源码内容了,学习源码一定是枯燥的。
2、Mybatis的源码撑死算Spring的一个模块,Mybatis的代码看起来简单不复杂。
3、方方面面都要掌握,不管是那个细节都要掌握到位,到时候扣细节都是非常非常方便的。
2、课程安排
4、整个Spring源码课程的安排【6-8次课搞定】
- 1、Spring工厂(容器)也就是IOC【源码】
- XML的读取,到后面的存储,到后面对象的创建、加工、缓存 很多方面进行分析。
- 2、AOP 代理设计
- Spring 真正 如何把代理融入 到Spring体系中
- 3、Spring与Mybatis的集成
- 4、事务是如何处理和封装的以及事务的这些属性包括隔离属性、包括传播属性底层都是怎么封装的,这是我们要考虑的内容。
- 5、SpringMVC 整个核心的运行流程这是大家需要去体会的,顺便会把父子容器的问题 给大家讲了,把里面涉及到的方方面面也会给大家分析到位,这个就是我们Spring源码课中和大家探讨的内容,这5大模块大家都了解掌握了的话,后续看SpringBoot的东西就会非常简单了,包括SpringCloud它里面的很多设计其实都是来自于这块。
3、搭建源码
- 6、搭建源码环境
- 搭建不搭建源码环境不重要。
- 有源码环境的话,可以给源码加注释,方便后续体会,后续复习。
- Maven搭建源码的话,不能加注释
- 从运行的角度来说 源码环境 运行代码是非常慢的
- 版本5.1足矣
- 获得源码的方式通过git的方式
-
点击build
- 搭建不搭建源码环境不重要。
剖析源码前的认知
1、Spring工厂为什么叫容器呢?
1、剖析源码围绕一个主题展开,就是Spring的工厂,但是也叫做容器,那好我想问问各位,为什么大家会把spring的工厂叫做容器呢?
作为整个spring 的工厂来讲,实际上工厂的责任是什么?工厂的责任是为了创建对象,但是创建完对象,他不仅仅是把这个对象创建起来,但同时他还得把这个对象存储在这个工厂当中,后续再给第二个调用者来使用。
2、比如说此时 有一个用户需要使用 User这个对象,工厂进行创建并存储,当第二个用户再来调用的时候就无需创建,直接使用就可以了。
3、能存储Order 能存储User 能存储一切它所创建的对象,那它不就是一个容器吗?当然会有一个前提,这些对象都得是单实例,因为我们当时讲spring的时候,它能创建单实例对象也能根据需要创建新的,如果是单实例的话指定为scope=singleton,如果是每次都创建新的需要指定为scope=prototype,工厂能存对象 存的是singleton对象,所以我们把工厂成为容器。
2、对于Spring来说它是怎么存单实例对象的呢?
- 实际上这个思路很简单,在Java的世界当中他要存多个对象,不仅要存后续还要用,那种结构能存多,还能方便查找和调用呢?
- 显示多个对象还方便查找 肯定是通过Map来存的。
- 有些人把Tomcat也称为容器,不仅要创建Servlet还要存储Servlet方便别人用,所以我们说但凡是容器的概念,它一定是要存储对象的。
- 这就是为啥有些人会把spring叫做容器,叫做IOC容器,有人也把它叫做工厂,其实工厂是来完成创建的,同时还要存储对象,即可称为工厂,也可称为容器。
3、ApplicationContext 的介绍
1、我们最常用的工厂是ApplicationContext 也叫应用上下文,这个工厂是Spring提供的较为高级的一个工厂,这个工厂复合了很多个功能,我们在编程的时候 用它最方便,但实际上它的角色都是被spring提供的其他工厂所分担了,ApplicationContext是我们编程过程中的一个门面,这就很类似于我们当时在讲Mybatis的时候,mybatis的门面是什么是SqlSession,用SqlSession来进行访问和操作,它给提供了很多方法,用起来比较方便,接口单一,但是实际上在实现的过程中,它是纷繁复杂的,而作为ApplicationContext这个工厂来讲,它也是spring编程当中的一个门面,它是一个很高级的东西,复合了很多其他类型 其他工厂的能力 集于一身,应用的时候使用高级工厂最方便,但是分析源码分析底层的时候 可不能使用ApplicationContext,功能太多了,分析它太乱了,那这个时候就得找到spring最为核心的底层工厂是BeanFactory
2、看一下相应的源码,是一个接口 后续通过实现类来进行使用,这里面的逻辑和当时我们将的ApplcationContext是完全一样的,ApplcationContext是工厂也是接口,一般会用ClassPathApplcationContext和BeanFactory是一样的。
BeanFactory2001年,两个Spring的作者,看注释写的很详细。
BeanFacotry严格遵循了类型单一职责的这个概念,所以这个工厂它演变成了一个非常复杂的体系,那么它这个体系是什么?
4、看BeanFactory类的继承关系。
5、看BeanFactory继承的各个类的职责单一的功能
-
BeanFactory:Spring体系底层工厂,定义工厂的基本操作
-
HierarchicalBeanFactory:父子容器的管理
-
ConfigurableBeanFactory:
- 可配置工厂,单实例,多实例scope
- 类型转化,后置处理bbean
-
AutowireCapableBeanFactory:
- 自动注入能力
- IntinitialBean DisponseBean
-
ListableBeanFactory
- 获取相关的配置信息
- constrainsBeanDefinition
- getBeanNameForType
-
DefaultListableBeanFactory
- 符合上述所有主要工厂能力 一个类型
-
XMLBeanFactory
- 使用基于XML配置的信息,完成对象的创建
- 符合上述所有主要工厂能力 一个类型
6、集成这些功能于一身的工厂有那些?
- DefaultListableBeanFactory
- XmlBeanFactory
解析源码的认知
1、读取XML配置文件,所有的文本文件不可能每次用的时候 现用现读取,因为IO的效率非常差,往往会把这些文件 读取到内存当中,那当然读取到内存当中来到虚拟机,那就不能以字符串的形式来体现了,它应该要以对象的形式来存在,那势必就要把 XML配置文件 封装成Java对象
BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));
2、从工厂容器中获得对象
User user = (User) beanFactory.getBean("u");
1、从上述代码中产生的疑惑
1、在Spring源码中怎么读取xml?
2、Spring怎么把xml数据封装成java对象?
3、Spring如何封装了这些对象?
4、Spring封装完成对象之后如何根据需要去创建对象?
2、Spring如何读取XML配置文件
通过new ClassPathResource(“配置文件的路径”)
1、Spring如何读取XML配置文件?
new ClassPathResource("配置文件的路径")
2、那么ClassPathResource是什么东西呢?
ClassPathResource是Resource接口的实现类,这个实现类是通过类加载器的方式,来获取输入流。
ClassPathResource是Resource的一个子类,Resource接口的目的是什么?
3、Resource目的:读取相关资源文件的内容 获得输入流
- 1、文件 xml .properties .txt
- 2、网络中的资源
1、那么ClassPathResource是什么东西呢?
2、Resource接口的目的是什么?可以读取的内容有那些?
- 目的:读取相关资源文件的内容 获得输入流
- 可以读取的内容有:
- 1、文件 xml .properties .txt
- 2、网络中的资源
3、InputStreamSource和Resource的关系
Resource继承了InputStreamSource,ClassPathResource实现了getInputStream根据类或者类加载器 获取输入流。要是其他类也是如此,这就是Spring对于IO的封装
我们在讲Mybatis的时候就说过,任何的一个框架在开发的过程当中都要对常用的功能进行封装,比如我们当时讲Mybatis的时候对反射进行了封装,今天讲的Spring就对IO进行了封装,对获取输入流进行了封装,ClassPathResource基于Resource完成的,基于ClassPathResource完成的。
4、那么这个Resource接口的实现类都有什么呢?
FileSystemResource
ClassPathResource
ByteArrayResource
ServletContextResouce
通过这些的子实现类,完成对具体IO输入流的获取,把文件的内容读取到虚拟机中。
5、Resource功能是什么?
把xml对应的内容通过Resouce读取到JVM中
6、如何把文件的内容读取到虚拟机中呢?
通过Resource的子实现类
7、在虚拟机当中我们这些配置内容是以什么形式体现的呢?
以对象的形式来存在,参考Mybatis
mybatis-config.xml 用 Configuration来体现
mapper 用 MappedStatement来体现
spring中的这些对象被封装成了一个个BeanDefinition来体现的
BeanDefinition对应的就是xml中一个个的bean标签,
最后这些一个个的bean标签 都会被存在 JVM当中或者Spring当中
8、我们怎么把XML文件内容封装成BeanDefine呢?
XML的解析,当时我们在讲Mybatis的时候说是通过Xpath的形式来解析。
spring的xml解析用的是SAX来解析的,把解析内容封装成了BeanDefine。
今天的文章孙帅suns的Spring第一集总结分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/68071.html