# springFramework **Repository Path**: interview_44/spring-framework ## Basic Information - **Project Name**: springFramework - **Description**: spring学习使用 - **Primary Language**: Java - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2021-04-22 - **Last Updated**: 2023-03-01 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ## Spring的初步了解,要深入学习,文末有配套博客 -[1、spring基础概念](#1spring基础概念) -[2、spring的IOC](#2spring的IOC) -[3、spring的AOP](#3spring的AOP) -[4、spring拓展](#4spring拓展) -[5、代理对象的生成与执行](#5代理对象的生成与执行) -[6、循环依赖](#6循环依赖) -[7、springMVC工作流程图](#7springMVC工作流程图) ### 1、spring基础概念 spring中使用的设计模式: 工厂模式:管理bean; 单例模式:bean唯一; 代理模式:增强代码 ; 享元模式:控制一级缓存,二级缓存,三级缓存。 IOC控制反转: 容器通过配置与注解,去实例化我们所有的bean,管理bean之间的依赖,实现类之间解耦,方便开发。 bean是否线程安全的? bean是线程不安全的。 作用域singletion : bean是单例的。 作用域prototype :每次会新建一个bean。 request :每次请求创建一个bean。 session : 每次会话开启一个bean。 @Configuration 的bean也是一个代理对象,代理对象的方法也是代理就可以拿到单例的方法对象。 ![](./picture/8、bean的生命周期.png) ### 2、spring的IOC #### 控制反转是一种思想,IOC容器存放bean ![](./picture/2、bean的ioc.png) 代码异常复杂,套用很多设计模式,代码量大,方法套用深。 就是加载资源文件,解析资源文件,反射出bean,执行构造,进行bean定义,加工bean定义,实例化对象,设置bean属性,最后得到bean实例。 ### DI - 依赖注入: 依赖注入的三种方式:(1)接口注入(2)Construct注入(3)Setter注入 ### 3、spring的AOP 面向切面编程,核心技术-动态代理技术,减少代码量。 1、前置事件,需要把advisor全部放到一个数组存储, ![](./picture/3、AOP依赖注入.png) 1、JDK动态代理:code-example在dynamicproxy 通过这种方式,被代理的对象可以在运行时动态改变, 需要控制的接口,控制的方式也可以动态改变,从而实现了非常灵活的动态代理关系。 有以下几点: 1)Interface:对于JDK proxy,业务类是需要一个Interface的,这也是一个缺陷 2)Proxy,Proxy 类是动态产生的,这个类在调用Proxy.newProxyInstance(targetCls.getClassLoader,targetCls.getInterface,InvocationHander)之后,会产生一个Proxy类的实例。实际上这个Proxy类也是存在的,不仅仅是类的实例。这个Proxy类可以保存到硬盘上。 3) Method:对于业务委托类的每个方法,现在Proxy类里面都不用静态显示出来 4) InvocationHandler: 这个类在业务委托类执行时,会先调用invoke方法。invoke方法再执行相应的代理操作,可以实现对业务方法的再包装 2、GClib动态代理:code-exmaple在gclib JDK的动态代理机制只能代理实现了接口的类,而不能实现接口的类就不能实现JDK的动态代理,cglib是针对类来实现代理的,他的原理是对指定的目标类生成一个子类,并覆盖其中方法实现增强,但因为采用的是继承,所以不能对final修饰的类进行代理。 ### 4、spring拓展 自定义bean,获取spring上下文容器。 ![](./picture/4、获取spring上下文容器.png) 对bean进行自定义处理,初始化方法,写可以前置后置。 ![](./picture/5、对bean前置,后置.png) bean销毁处理. ![](./picture/6、bean销毁%20处理.png) ### 5、代理对象的生成与执行 ![](./picture/7、代理对象的生成与执行.png) 动态代理生成其实在AOP已经占了绝大部分了,基本上跟aop的流程图差不多。 执行代理方法,执行动态代理DynamicAdvisedInterceptor中的interceptor(),把Advice和Advisor,配置为MethodInterveptor,并组成一个chain ,然后根据自己代码,在业务逻辑前后都可以执行代理方法。 ### 6、循环依赖 ![](./picture/9、循环依赖解释.png) ![](./picture/10、spring如何解决循环依赖.png) 1、Abean初始化的时候,依赖了Bbean,Bbean里面又依赖了Abean,那么久造成了循环依赖了。 2、Abean初始化被扫描生成beanDefinition放入spring的容器beanDefinitionMap。 3、Abean通过构造函数生成bean原始对象,把bean的lambda表达式放入三级缓存容器singletionFactory单例池。 4、进行DI依赖注入属性,发现要Bbean,就到一级缓存singletionObjects中去找Bbean,发现没有,就去初始化Bbean。 5、Bbean执行初始化,被扫描生成beanDefinition放入spring的容器beanDefinitionMap。 6、Bbean通过构造函数生成bean原始对象,把bean的lambda表达式放入三级缓存容器singletionFactory单例池。 7、Bbean对象依赖注入,发现有属性Abean,就到一级缓存singletionObjects中找Bbean,在单例池中没找到,就会去三级缓存容器singletionFactory单例池中找,如果找到了,此时他就知道循环依赖了。 8、Abean提前完成AOP,之后放入二级缓存earlySingletionObjects。 9、Bean获得了Abean的代理类,自己可以完成AOP。放入一级缓存singletionObjects。 10、Abean此时获得了Bbean,可以继续注入属性。 11、Abean完成了依赖注入后,发现自己已经提前AOP了,就不需要AOP了,直接从二级缓存earlySingletionObjects拿出代理类。 12、Abean的代理类初始化完成。 ### 7、springMVC工作流程图 ![](./picture/11、mvn工作流.png) ### 8、spring事务 spring事务的底层原理与mysql隔离级别一致。 spring 代理对象执行事务代理方法 1、建立数据库连接 2、set commitAuto设置为true 3、遇到sql执行sql 4、提交 5、代理逻辑提交 同一个类中方法调用,并不会开启一个事务? @Transactional a(){ this.b(); } @Transactional b(){ } b()的@Transactional不会开启一个事务,因为是本类,并不是代理类除非注入一个代理对象调用b(),才会报错。 spring事务传播机制 PROPAGATION_REQUIRED Spring默认的传播机制,能满足绝大部分业务需求,如果外层有事务,则当前事务加入到外层事务,一块提交,一块回滚。如果外层没有事务,新建一个事务执行 PROPAGATION_REQUES_NEW 该事务传播机制是每次都会新开启一个事务,同时把外层事务挂起,当当前事务执行完毕,恢复上层事务的执行。如果外层没有事务,执行当前新开启的事务即可 PROPAGATION_SUPPORT 如果外层有事务,则加入外层事务,如果外层没有事务,则直接使用非事务方式执行。完全依赖外层的事务 PROPAGATION_NOT_SUPPORT 该传播机制不支持事务,如果外层存在事务则挂起,执行完当前代码,则恢复外层事务,无论是否异常都不会回滚当前的代码 PROPAGATION_NEVER 该传播机制不支持外层事务,即如果外层有事务就抛出异常 PROPAGATION_MANDATORY 与NEVER相反,如果外层没有事务,则抛出异常 PROPAGATION_NESTED 嵌套事务 父方法异常,回滚子方法;子方法异常,不会回滚父方法。 **配套学习博客** 1. [为什么我建议你去阅读优秀的源码](https://mp.weixin.qq.com/s/mC7BklvQwMJrQ_V0k4n1vA) 2. [有哪些你不知道的阅读源码的技巧](https://mp.weixin.qq.com/s/Nt8ibQxdopDq5_6yRpYC1g) 3. [SpringIOC源码解析(上)](https://mp.weixin.qq.com/s/0zDCy0eQycdM8M9eHGuLEQ) 4. [SpringIOC源码解析(下)](https://mp.weixin.qq.com/s/z-DZxBWOSSaFfQXlA0TSKw) 5. [SpringIOC源码解析(基于注解)](https://mp.weixin.qq.com/s/xqDPttr53rxLBi8t8kIQDg) 6. [基于注解的SpringAOP源码解析(一)](https://mp.weixin.qq.com/s/yMw1MZIRjQ4c504SSuPFaw) 7. [基于注解的SpringAOP源码解析(二)](https://mp.weixin.qq.com/s/kxbdat_T0io6xEnD48HK-g) 8. [基于注解的SpringAOP源码解析(三)](https://mp.weixin.qq.com/s/TORZGi2AX8hV1gNf1qNZUA) 9. [SpringJDBC源码解析](https://mp.weixin.qq.com/s/cmdlQ2LUi-7IDC6rCKqWOg) 10. [Spring @Import注解源码解析](https://mp.weixin.qq.com/s/dNOBwMPHKdccmeJFWzzTOg) 11. [Spring事务源码解析(一)@EnableTransactionManagement注解](https://mp.weixin.qq.com/s/FU3hznLFspCcHYJs-x8h2Q) 12. [Spring事务源码解析(二)获取增强](https://mp.weixin.qq.com/s/5tTrdl5GuD9WAyuHNUvW8w) 13. [Spring事务源码解析(三)](https://mp.weixin.qq.com/s/H933x4Upa8Vgl1EkuTZBtQ) 14. [SpringMVC源码解析(一)](https://mp.weixin.qq.com/s/V8iwW-rpaQsISiis7hF0aw) 15. [SpringMVC源码解析(二)](https://mp.weixin.qq.com/s/d7Ne8EI-e3VyGddEh9BvMA) 16. [SpringBoot自动装配原理解析](https://mp.weixin.qq.com/s/I3-sM55JSb4BFJ-zPosZgQ) 17. [SpringBoot源码解析:创建SpringApplication对象实例](https://mp.weixin.qq.com/s/h-pvfCSsYIlVSCHd9oCrEg) 18. [SpringApplication到底run了什么(上)](https://mp.weixin.qq.com/s/TuQR1kKqHrAQOxnRCfdFOw) 19. [SpringApplication到底run了什么(下)](https://mp.weixin.qq.com/s/rtR3dOWSqG60dVJoR9tCEA) 20. [SpringBoot嵌入式Tomcat的自动配置原理](https://mp.weixin.qq.com/s/XdxQgAYqarGpiSS3n7tp4g) 21. [SpringBoot健康检查实现原理](https://mp.weixin.qq.com/s/SFc2-NZZ3Nv7bX1QRfqQ7g) ![1](https://shiyujun.cn/img/gongzhonghao.jpg)