title: 暑假最后几天!肝爆(手写)一个Spring之Day1
date: 2022-08-13 23:26:59
categories:
- 手写spring
Day01—Spring预热
已经完成了基本,代码地址
Github:https://github.com/luelueking/My_Spring_Source
Gitee:https://gitee.com/luelueking/My_Spring_Source
不废话,直接进入正文!!!
Spring的设计初衷
- 根本使命:简化开发
- 4个关键策略(如何完成使命):
- 基于POJO的轻量级和最小侵入性编程
- 通过依赖注入和面向接口实现松耦合
- 基于切面和惯性进行声明式编程
- 通过切面和模版减少样版式代码
- 通过面相Bean(BOP)、依赖注入(DI)及面向切面(AOP)这三种方式兑现吹过的🐮
Spring的系统架构
-
核心容器
- spring-beans和spring-core:spring的核心模块,包含了控制反转(IoC)和依赖注入(DI)。
- BeanFactory用IoC对应用程序的配置和依赖性规范与实际的应用程序代码进行分离。
- 注:BeanFactory实例化后并不会实例化Bean
- spring-context:构建于核心模块之上,扩展了BeanFactory,为它添加了Bean生命周期控制、框架事件体系及资源加载透明化等功能。
- ApplicationContext是该模块的核心接口,其超类是BeanFactory,不同点在于ApplicationContext实例化后自动化对所有的单实例Bean进行实例化与依赖关系的装配,使之处于待用状态。
- Spring-context-support:对SpringIoC容器及IoC子容器的扩展支持
- Spring-context-indexer:Spring类的管理组件和Classpath扫描组件
- Spring-expression:统一表达式语言(EL)的扩展,可以查询、管理运行中的对象,同时也可以方便的调用对象方法、以及操作数组、集合等。
- spring-beans和spring-core:spring的核心模块,包含了控制反转(IoC)和依赖注入(DI)。
-
AOP和设备支持
- spring-aop:另一个核心模块,AOP主要实现模块。
- spring-aspects:集成自AspectJ框架,主要为Sping提供多种AOP实现方法。
- spring-instrument:基于JavaSE中的java.lang.instrument进行设计的,应该算是AOP的一个支援模块,主要作用是JVM启用时生成的一个代理类。
-
数据访问与集成
- spring-jdbc:Spring提供的JDBC抽象框架的主要实现模块,用于简化Spring JDBC操作。
- spring-tx:Spring JDBC事务控制实现模块。
- spring-orm:ORM框架支持模块,主要集成Hibernate,Java Persistence API(JPA)和Java Data Objects(JDO)用于资源管理、数据访问对象的实现和事务策略。
- spring-oxm:提供一个抽象层以支撑OXM(Object和XML的映射)
- spring-jms:能够发送和接受信息
-
Web组件
- spring-web:Spring提供的最基础的Web支持,主要简历在核心容器之上,通过Servlet或者Listeners来初始化Ioc容器,也包含一些与Web相关的支持。
- spring-webmvc:Spring MVC
- spring-websocket:与Web前端进行全双工通信的协议。
- spring-webflux:一个新的非堵塞函数式Reactive Web框架,可以用来构建异步的、非阻塞的、事件驱动的服务、扩展性非常好。
-
通信报文
- spring-message:为Spring框架集成一些基础的报文传送应用。
-
集成测试
- spring-test:提供测试支持
-
集成兼容
- spring-framework-bom:主要解决Spring的不同模块依赖版本不同的问题
-
模块之间依赖关系
Spring IoC运行时序
- IoC回顾:Inversion of Control 控制反转,就是把原来代码里需要实现的对象创建、依赖,反转给容器帮忙实现。
- 这里我画了一张详细的时序图
- 简单概括就是三个基本步骤:
- 初始化的入口由容器实现中的refresh()方法完成调用
- 对Bean定义载入IoC容器使用的方法是loadBeanDefinition()
- 注册之后就可以通过BeanFactory和ApplicationContext来享受SpringIoC的服务了
Spring DI运行时序
-
DI回顾:Dependency Injection 依赖注入
-
DI发生的时间:
- 用户第一次调用getBean()方法时,IoC容器触发依赖注入
- 当用户在配置文件中将元素配置了lay-init=false属性是,即让容器在解析注册Bean定义时进行预实例化,触发依赖注入(延时加载:可以提高第一次获取Bean的性能)
-
主要分为二个步骤:
- 调用createBeanInstance()方法生成Bean所包含的Java对象实例
- 调用populateBean()方法对Bean属性的依赖注入进行处理
-
IoC容器是如何将属性值注入Bean实例对象上的:
- 对于集合类型的属性,将属性值解析为目标类型的结合后直接赋值给属性
- 对于非集合类型的属性,大量使用JDK的反射机制,通过属性的getter()方法获取指定属性注入前的值,同时调用属性的setter()方法为属性设置注入后的值
-
详细时序图
Spring AOP时序
- AOP回顾:Aspect Oriented Programming 面向切面编程,可以通过预编译和运行时的动态代理,实现在不修改源代码的情况下给程序动态统一添加功能。
- 大致步骤:
- BeanPostProcessor初始化
- 选择代理策略
- 调用代理方法
- 触发通知
Spring MVC时序
-
一张经典图片回顾mvc的请求处理流程:
-
-
九大组件:
- HandlerMapping:用来查找Handler的,也就是处理器,可以是类也可以是方法。
- 例子:标注了***@RequestMapping***的每个方法就可以看成一个Handler。
- 作用:找到请求对应的处理器Handler和Interceptor
- HandlerAdapter:适配器,因为Handler形式任意,但请求交给Servlet的方法节后都是doService(HttpServletRequest req,HttpServletResponse res)形式的,终究适配过程就是靠它。
- HandlerExceptionResolver:处理Handler产生的异常情况的组件
- ViewResolver:视图解析器。
- 核心方法:resolveViewName(),一个参数是String类型ViewName,另一个是Locale
- 作用:将String类型的视图名和Locale解析为View类型的视图
- 默认情况下,会为我们自动配置一个InternalResourceViewResolver
- RequestToViewNameTranslator:从请求中获取ViewName。因为ViewResolver根据ViewName查找View,但有些Handler处理完成之后没有设置View和ViewName。
- LocaleReslover:从请求中解析Locale。
- ThemeResolver:解析主题的。
- MultipartReslover:处理上传请求,通过将普通的请求包装成MultipartHttpServletRequest来实现(使其可以上传文件等等)。
- FlashMapManager:管理FlashMap。
- 什么是FlashMap:用于重定向时的参数传递
- HandlerMapping:用来查找Handler的,也就是处理器,可以是类也可以是方法。
-
大致步骤可分为三步:
- ApplicationContext初始化时用Map保存所有的URL和Controller类的对应关系。
- 根据请求URL找到对应的Controller,并从Controller中找到处理请求的方法。
- 将Request参数绑定到方法的参数上,执行方法处理请求,并返回结果视图。
-
时序图(画的好累🤮,但是为了职业素养)