创意电子
标题:
一文看懂Spring核心概念和源码解读
[打印本页]
作者:
后端研发Marion
时间:
2021-3-13 11:21
标题:
一文看懂Spring核心概念和源码解读
# 一文看懂Spring核心概念和源码解读
## 本文目次
一、Spring框架的模块组成
二、Spring的核心原理
三、Spring的两大核心接口:BeanFactory和ApplicationContext
四、Spring容器中的Bean
五、单例Bean的线程安全和并发问题(重点)
六、Spring的事务处理
七、Spring框架中用到的设计模式
八、Spring框架的变乱类型
## 一、Spring框架的模块组成
登录/注册后可看大图
1. 核心组件
1. 核心容器(Core Container)
2. AOP(Aspect Oriented Programming)
3. 设备支持(Instrument)
4. 数据访问及集成(Data Access/Integratioin)
5. Web
6. 报文发送(Messaging)
7. Test等模块。
2. Spring的优点
1. 低侵入式
2. DI机制减少组件耦合性
3. AOP
4. 扩展性
## 二、Spring的核心原理
Spring框架最核心的原理:IOC 和 AOP。IOC让相互协作的组件保持疏松的耦合,而AOP编程答应把遍布于应用各层的功能分离出来形成可重用的功能组件。
### 1. 控制反转 IOC
1. 容器控制创建对象,低沉对象之间耦合性,利于功能复用
2. 创建对象不须要new,而是利用JAVA反射机制根据配置文件动态创建对象和管理对象
3. Spring中三种注入方式:
1. 构造器注入
2. setter方法注入
3. 基于注解注入(@Autowire)
### 2. 面向切面 AOP
1. AOP的理解
抽取并封装多个对象的公共行为和逻辑成一个可重用的模块`切面(Aspect)`
登录/注册后可看大图
2. 静态署理(AspectJ)和动态署理(Spring AOP)
1. `静态署理`:AspectJ是静态署理的增强,编译时将AspectJ植入Java字节码中,运用时就是增强后的署理对象
2. `动态署理`:动态署理不会修改Java字节码,是每次运行时在内存中临时为方法生成一个AOP对象,这个AOP对象包含了目标对象的全部方法,而且在特定的切点做了增强处理,并回调原对象的方法
3. Spring AOP动态署理的两种方式(JDK和CGLIB)
1. `JDK`:JDK动态署理只提供接口的署理,不支持类的署理。
登录/注册后可看大图
2. `CGLIB`:是一个代码生成的类库,可以在运行时动态的生成指定类的一个子类对象,并覆盖此中特定方法并添加增强代码,从而实现AOP。
登录/注册后可看大图
3. GLIB是通过继承的方式做的动态署理,因此如果某个类被标志为final,那么它是无法利用CGLIB做动态署理的。
登录/注册后可看大图
4. AOP的核心概念
登录/注册后可看大图
1. `切面(Aspect)`:被抽取的公共模块,可能会横切多个对象。 在Spring AOP中,切面可以利用通用类(基于模式的风格) 大概在普通类中以 @AspectJ 注解来实现。
登录/注册后可看大图
2. `连接点(Join point)`:指方法,在Spring AOP中,一个连接点 总是 代表一个方法的实验。
3.`关照(Advice)`:在切面的某个特定的连接点(Join point)上实验的动作。关照有各种类型,此中包括“around”、“before”和“after”等关照。许多AOP框架,包括Spring,都是以拦截器做关照模型, 并维护一个以连接点为中心的拦截器链。
登录/注册后可看大图
登录/注册后可看大图
4. `切入点(Pointcut)`:切入点是指 我们要对哪些Join point进行拦截的定义。通过切入点表达式,指定拦截的方法,比如指定拦截add*、search*。
登录/注册后可看大图
5. `引入(Introduction)`:(也被称为内部类型声明(inter-type declaration))。声明额外的方法大概某个类型的字段。Spring答应引入新的接口(以及一个对应的实现)到任何被署理的对象。例如,你可以利用一个引入来使bean实现 IsModified 接口,以便简化缓存机制。
6. `目标对象(Target Object)`: 被一个大概多个切面(aspect)所关照(advise)的对象。也有人把它叫做 被关照(adviced) 对象。 既然Spring AOP是通过运行时署理实现的,这个对象永久是一个 被署理(proxied) 对象。
7. `织入(Weaving)`:指把增强应用到目标对象来创建新的署理对象的过程。Spring是在运行时完成织入。
8. 切入点(pointcut)和连接点(join point)匹配的概念是AOP的关键,这使得AOP差别于其它仅仅提供拦截功能的旧技能。 切入点使得定位关照(advice)可独立于OO层次。
登录/注册后可看大图
5. AOP的应用场景
登录/注册后可看大图
6. AOP的实战场景
登录/注册后可看大图
登录/注册后可看大图
登录/注册后可看大图
登录/注册后可看大图
登录/注册后可看大图
登录/注册后可看大图
登录/注册后可看大图
登录/注册后可看大图
7. 利用SpringAop的留意事项
登录/注册后可看大图
参考[探秘Spring AOP](https://www.imooc.com/learn/869)课程截图
登录/注册后可看大图
登录/注册后可看大图
登录/注册后可看大图
登录/注册后可看大图
登录/注册后可看大图
登录/注册后可看大图
登录/注册后可看大图
### 三、Spring的两大核心接口:BeanFactory和ApplicationContext
BeanFactory和ApplicationContext是Spring的两大核心接口,都可以当做Spring的容器。此中ApplicationContext是BeanFactory的子接口。
1. ApplicationContext 是 BeanFactory 的子接口,功能更全
1. BeanFactory是Spring里面最底层的接口,包含了各种Bean的定义,读取bean配置文档,管理bean的加载、实例化,控制bean的生命周期,维护bean之间的依赖关系。ApplicationContext是BeanFactory的派生接口,除了提供BeanFactory所具有的功能外,还提供了更完备的框架功能:
2. 继承MessageSource,因此支持国际化。
3. 同一的资源文件访问方式。
4. 提供在监听器中注册bean的变乱。
5. 同时加载多个配置文件。
6. 载入多个(有继承关系)上下文 ,使得每一个上下文都专注于一个特定的层次,比如应用的web层。
2. 加载方式
1. `BeanFactroy` 采用的是延迟加载形式来注入Bean,即只有在利用到某个Bean时(调用getBean()),才对该Bean进行加载实例化。如许,我们就不能发现一些存在的Spring的配置问题。如果Bean的某一个属性没有注入,BeanFacotry加载后,直至第一次利用调用getBean方法才会抛出异常
2. `ApplicationContext` 是在容器启动时,一次性创建了全部的Bean。如许,在容器启动时,我们就可以发现Spring中存在的配置错误,如许有利于查抄所依赖属性是否注入。 ApplicationContext启动后预载入全部的单实例Bean,通过预载入单实例bean ,确保当你须要的时候,你就不用等待,因为它们已经创建好了。
相对于基本的BeanFactory,ApplicationContext 唯一的不敷是占用内存空间。当应用程序配置Bean较多时,程序启动较慢。
3. 创建方式
1. BeanFactory 通常以编程的方式被创建。
2. ApplicationContext 除了编程方式,还能以声明的方式创建,如利用ContextLoader。
4. 注册方式
BeanFactory和ApplicationContext都支持BeanPostProcessor、BeanFactoryPostProcessor的利用,但两者之间的区别是:BeanFactory须要手动注册,而ApplicationContext则是自动注册。
### 四、Spring容器中的Bean
#### 1. Bean的作用域
1. `singleton(单例)`,在spring容器中仅存在一个Bean实例,Bean以单例方式存在,bean作用域范围的默认值。
2. `prototype(原型)`,每次从容器中调用Bean时,都返回一个新的实例,即每次调用getBean()时,相当于实验newXxxBean()。
3. `request`,每次HTTP请求都会创建一个新的Bean,该作用域仅实用于web的WebApplicationContext环境。
4. `session`,同一个HTTP Session共享一个Bean,差别Session利用差别的Bean。该作用域仅实用于web的WebApplicationContext环境。
5. `globalSession`,同一个全局 Session 共享一个 bean,用于 Portlet, 该作用域仅用于 WebApplication 环境。
#### 2. Bean注入的几种方式
1. 基于注解 @Autowired 的自动装配(最常用)
1. authwire3个属性值:constructor、byName、byType
2. 匹配多个Bean怎样注入:DefaultListableBeanFactory 的 determineAutowireCandidate
2. 基于构造方法注入
3. 基于Setter方法注入
#### 3. Bean的自动装配
在spring中,对象无需本身查找或创建与其关联的其他对象,由容器负责把须要相互协作的对象引用赋予各个对象,利用autowire来配置自动装载模式
1. 自动装配种类
1. no:默认的方式是不进行自动装配的,通过手工设置ref属性来进行装配bean。
2. byName:通过bean的名称进行自动装配,如果一个bean的 property 与另一bean 的name 相同,就进行自动装配。
3. byType:通过参数的数据类型进行自动装配。
4. constructor:利用构造函数进行装配,而且构造函数的参数通过byType进行装配。
5. autodetect:自动探测,如果有构造方法,通过 construct的方式自动装配,否则利用
6. byType的方式自动装配。
2. @Autowired和@Resource之间的区别
1. @Autowired默认是按照类型装配注入的,默认环境下它要求依赖对象必须存在(可以设置它required属性为false)。
2. @Resource默认是按照名称来装配注入的,只有当找不到与名称匹配的bean才会按照类型来装配注入。
#### 4. Bean的生命周期和加载流程(重点)
Spring Bean 的生命周期分为四个阶段和多个扩展点。扩展点又可以分为影响多个Bean和影响单个Bean。实例化和属性赋值对应构造方法和setter方法的注入,初始化和烧毁是用户能自定义扩展的两个阶段。
登录/注册后可看大图
登录/注册后可看大图
1. 四个阶段(实例化 -> 属性赋值 -> 初始化 -> 烧毁)
1. 实例化 Instantiation
2. 属性赋值 Populate
3. 初始化 Initialization
登录/注册后可看大图
4. 烧毁 Destruction
2. 多个扩展点
1. 影响多个Bean
1. BeanPostProcessor
2. InstantiationAwareBeanPostProcessor
2. 影响单个Bean
1. Aware
1. Aware Group1
1. BeanNameAware
2. BeanClassLoaderAware
3. BeanFactoryAware
1. Aware Group2
1. EnvironmentAware
2. EmbeddedValueResolverAware
3. ApplicationContextAware(ResourceLoaderAware\ApplicationEventPublisherAware\MessageSourceAware)
3. 生命周期
1. InitializingBean,初始化Bean
2. DisposableBean,烧毁Bean
##### 4. 源码解读参考[一招带你搞定Spring源码,小白也能听懂的spring源码过程](https://www.ixigua.com/6898673954483864077)
1. Spring启动加载流程
1. XML加载
2. 解析
3. 创建实例
4. 利用
5. 烧毁
2. 容器的作用
1. 存放bean
2. bean的数据布局
3. list
4. set
5. map(K-V)
3. IOC容器
1. `BeanDefinition`的定义信息
2. 抽象定义规范接口`BeanDefinitionReader`
4. 创建对象方式
1. new
2. 反射怎样创建对象
3. 工厂模式
4. Spring中bean的默认scope是单例的
5. xml和注解中定义的是bean的定义信息,通过抽象定义接口解析到BeanDefinition
6. BeanDefinition通过new反射到实例化
1. 实例化:在堆中开辟一块空间,属性都是默认值
2. 初始化:给属性赋值
1. 填充属性
2. 实验初始化方法`init-method`
7. 初始化到完备对象
8. Spring的扩展性设计
9. BeanDefinition到BeanFactory
10. PostProcessor增强器,进行扩展实现
11. BeanFactoryPostProcessor
1. 解析配置文件,处理占位符`placeholderConfigrerSupport`
2. 可以自行继承PostProcessor
3. `registerListeners`
12. bean的生命周期
1. 实例化`反射`
2. 填充属性`populateBean`
3. 实验aware接口须要实现的方法`invokeAwareMethods`
1. aware接口存在的意义是方便spring中的bean对象获取容器对象中的属性值
4. BeanPostProcessor
1. before
2. init-method`invokeInitMethods`
3. after
4. aop扩展
5. 完备对象
6. 烧毁流程
13. Environment
1. System.getEnv()
2. System.getProperties()
14. 如果我想在spring生命周期的差别阶段做差别的处理工作?
1. 观察者模式:监听器、监听时间、多播器
15. spring中的do方法
## 五、单例Bean的线程安全和并发问题(重点)
单例Bean是Spring容器默认的方式,全部线程都共享一个单例实例Bean,确实会存在并发的问题。对于原型Bean,每次创建一个新对象,也就是线程之间并不存在Bean共享,天然是不会有线程安全的问题。
### 1、单例Bean的线程安全问题
1. 无状态对象(Stateless Bean)(`线程安全`)
1. 没有实例变量的对象,不能生存数据,是不变类,是线程安全的。
2. bean一旦实例化就被加进会话池中,各个用户都可以共用。即利用户已经灭亡,bean 的生命期也不一定结束,它可能依然存在于会话池中,供其他用户调用。
3. 由于没有特定的用户,那么也就不能保持某一用户的状态,以是叫无状态bean。
4. 无状态Bean,也就是线程中的操作不会对Bean的成员实验查询以外的操作,那么这个单例Bean是线程安全的。比如Spring mvc 的 Controller、Service、Dao等,这些Bean大多是无状态的,只关注于方法本身。
2. 有状态对象(Stateful Bean)(`线程不安全`) :
1. 就是有实例变量的对象,可以生存数据,是非线程安全的。
2. 每个用户有本身特有的一个实例,在用户的生存期内,bean保持了用户的信息,即“有状态”;一旦用户灭亡(调用结束或实例结束),bean的生命期也告结束。
3. 即每个用户最初都会得到一个初始的bean。
### 2、线程安全问题的管理办法
1. 管理方案
1. 只管避免在Bean对象中定义可变的成员变量,避免有状态的Bean。
2. 如果确实须要利用状态的Bean,则在Bean对象中定义一个ThreadLocal成员变量,将须要的可变成员变量生存在ThreadLocal中。
3. 也可以通过加锁的方法来管理线程安全,这种以时间换空间的场景在高并发场景下显然是不实际的,还是优先推荐利用ThreadLocal。
2. 多线程相同变量访问冲突问题:ThreadLocal和线程同步机制
1. 线程同步:`时间换空间`
2. ThreadLocal:`空间换时间`
3. ThreadLocal会为每一个线程提供一个独立的变量副本,从而隔离了多个线程对数据的访问冲突。因为每一个线程都拥有本身的变量副本,从而也就没有须要对该变量进行同步了。
4. ThreadLocal提供了线程安全的共享对象,在编写多线程代码时,可以把不安全的变量封装进ThreadLocal.
## 六、Spring的事务处理
### 1、Spring事务的种类
1. 编程式事务,利用TransactionTemplate。
2. 声明式事务,建立在AOP之上的。其本质是通过AOP功能,对方法前后进行拦截,将事务处理的功能编织到拦截的方法中,也就是在目标方法开始之前加入一个事务,在实验完目标方法之后根据实验环境提交大概回滚事务。
3. 区别:声明式事务最细粒度只能作用到方法级别,无法做到像编程式事务那样可以作用到代码块级别
### 2、Spring事务的隔离级别(5种)
1. 事务的隔离级别
### 3、Spring事务的传播行为(7种)
1. Spring事务的传播行为说的是,当多个事务同时存在的时候,Spring怎样处理这些事务的行为
## 七、Spring框架中用到的设计模式
### 1. 工厂模式
1. Spring利用工厂模式可以通过 BeanFactory 或 ApplicationContext 创建 bean 对象。两者的区别,
1. BeanFactory :延迟注入(利用到某个 bean 的时候才会注入),占用更少的内存,程序启动速度更快。
2. ApplicationContext :容器启动的时候,一次性创建全部 bean 。ApplicationContext除了BeanFactory的功能,另有额外更多功能,实际开发中,ApplicationContext更常用。
2. ApplicationContext的三个实现类:
1. ClassPathXmlApplication:把上下文文件当成类路径资源。
2. FileSystemXmlApplication:从文件系统中的 XML 文件载入上下文定义信息。
3. XmlWebApplicationContext:从Web系统中的XML文件载入上下文定义信息。
### 2. 单例模式
Spring 中 Bean 的默认作用域就是 singleton(单例)的。利用单例模式的好处
1. 对于频繁利用的对象,可以省略创建对象所花费的时间,这对于那些重量级对象而言,是非常可观的一笔系统开销;
2. 由于 new 操作的次数减少,因而对系统内存的利用频率也会低沉,这将减轻 GC 压力,紧缩 GC 停顿时间。
### 3. 署理模式
Spring的AOP功能用到了JDK的动态署理和CGLIB字节码生成技能。
### 4. 模板方法
用来管理代码重复的问题。比如. RestTemplate, JmsTemplate, JpaTemplate等。
### 5. 观察者模式
定义对象键一种一对多的依赖关系,当一个对象的状态发生改变时,全部依赖于它的对象都会得到关照被制动更新,如Spring中listener的实现:ApplicationListener。
## 八、Spring框架的变乱类型
1. 上下文更新变乱(ContextRefreshedEvent)
2. 上下文开始变乱(ContextStartedEvent)
3. 上下文停止变乱(ContextStoppedEvent)
4. 上下文关闭变乱(ContextClosedEvent)
5. 请求处理变乱(RequestHandledEvent)
## 参考资料
- [一招带你搞定Spring源码,小白也能听懂的spring源码过程](https://www.ixigua.com/6898673954483864077)
- [Spring框架小白的蜕变](https://www.imooc.com/learn/1108)
- [探秘Spring AOP](https://www.imooc.com/learn/869)
- [2021最新Java面经整理 | 框架篇(一)Spring框架](https://blog.csdn.net/shipfei_csdn/article/details/109530018)
作者:
好泰来
时间:
2021-3-13 19:30
详细...
作者:
小船掀大浪
时间:
2021-3-14 07:51
转发了
作者:
驰光工作室
时间:
2021-3-14 07:54
很像是慕课的教程
作者:
徐忠明勿忘初心
时间:
2021-3-14 11:37
转发了
欢迎光临 创意电子 (https://wxcydz.cc/)
Powered by Discuz! X3.4