Spring源码阅读目录
第一部分——IOC篇
第一章 Spring之最熟悉的陌生人——IOC
第二章 Spring之假如让你来写IOC容器——加载资源篇
第三章 Spring之假如让你来写IOC容器——解析配置文件篇
第四章 Spring之假如让你来写IOC容器——XML配置文件篇
第五章 Spring之假如让你来写IOC容器——BeanFactory和FactoryBean
第六章 Spring之假如让你来写IOC容器——Scope和属性填充
第七章 Spring之假如让你来写IOC容器——属性填充特别篇:SpEL表达式
第八章 Spring之假如让你来写IOC容器——拓展篇
第九章 Spring之源码阅读——环境搭建篇
第十章 Spring之源码阅读——IOC篇
第二部分——AOP篇
第十一章 Spring之不太熟的熟人——AOP
第十二章 Spring之不得不了解的内容——概念篇
第十三章 Spring之假如让你来写AOP——AOP联盟篇
第十四章 Spring之假如让你来写AOP——雏形篇
第十五章 Spring之假如让你来写AOP——Joinpoint(连接点)篇
第十六章 Spring之假如让你来写AOP——Pointcut(切点)篇
第十七章 Spring之假如让你来写AOP——Advice(通知)上篇
第十八章 Spring之假如让你来写AOP——Advice(通知)下篇
第十九章 Spring之假如让你来写AOP——番外篇:Spring早期设计
第二十章 Spring之假如让你来写AOP——Aspect(切面)篇
第二十一章 Spring之假如让你来写AOP——Weaver(织入器)篇
第二十二章 Spring之假如让你来写AOP——Target Object(目标对象)篇
第二十三章 Spring之假如让你来写AOP——融入IOC容器篇
第二十四章 Spring之源码阅读——AOP篇
第三部分——事务篇
第二十五章 Spring之曾经的老朋友——事务
第二十六章 Spring之假如让你来写事务——初稿篇
第二十七章 Spring之假如让你来写事务——铁三角篇
第二十八章 Spring之假如让你来写事务——属性篇
第二十九章 Spring之假如让你来写事务——状态篇
第三十章 Spring之假如让你来写事务——管理篇
第三十一章 Spring之假如让你来写事务——融入IOC容器篇
第三十二章 Spring之源码阅读——事务篇
第四部分——MVC篇
第三十三章 Spring之梦开始的地方——MVC
第三十四章 Spring之假如让你来写MVC——草图篇
第三十五章 Spring之假如让你来写MVC——映射器篇
第三十六章 Spring之假如让你来写MVC——拦截器篇
第三十七章 Spring之假如让你来写MVC——控制器篇
第三十八章 Spring之假如让你来写MVC——适配器篇
第三十九章 Spring之假如让你来写MVC——番外篇:类型转换
第四十章 Spring之假如让你来写MVC——ModelAndView篇
第四十一章 Spring之假如让你来写MVC——番外篇:数据绑定
第四十二章 Spring之假如让你来写MVC——视图篇
第四十三章 Spring之假如让你来写MVC——上传文件篇
第四十四章 Spring之假如让你来写MVC——异常处理器篇
第四十五章 Spring之假如让你来写MVC——国际化篇
第四十六章 Spring之假如让你来写MVC——主题解析器篇
第四十七章 Spring之假如让你来写MVC——闪存管理器篇
第四十八章 Spring之假如让你来写MVC——请求映射视图篇
第四十九章 Spring之假如让你来写MVC——番外篇:属性操作
第五十章 Spring之假如让你来写MVC——融入IOC容器篇
第五十一章 Spring之源码阅读——MVC篇
第五部分——Boot篇
第五十二章 Spring之再进一步——Boot
第五十三章 Spring之假如让你来写Boot——环境篇
第五十四章 Spring之假如让你来写Boot——注解篇(上)
第五十五章 Spring之假如让你来写Boot——注解篇(下)
第五十六章 Spring之假如让你来写Boot——SPI篇
第五十七章 Spring之假如让你来写Boot——配置文件篇(上)
第五十八章 Spring之假如让你来写Boot——配置文件篇(下)
第五十九章 Spring之假如让你来写Boot——番外篇:再谈Bean定义
第六十章 Spring之假如让你来写Boot——自动装配篇
第六十一章 Spring之假如让你来写Boot——番外篇:杂谈Starter
第六十二章 Spring之假如让你来写Boot——番外篇:重构BeanFactory
第六十三章 Spring之假如让你来写Boot——番外篇:再谈ApplicationContext
第六十四章 Spring之假如让你来写Boot——内嵌Web容器篇
第六十五章 Spring之假如让你来写Boot——Main方法启动篇
第六十六章 Spring之最终章——结语篇
文章目录
前言
对于Spring一直都是既熟悉又陌生,说对它熟悉吧,平时用用没啥问题,但面试的时候被问的一脸懵逼,就很尴尬,都不好意思在简历上写着熟悉Spring了
所以决定花点时间研究研究Spring的源码。主要参考的书籍是:《Spring源码深度解析(第2版)》、《Spring揭秘》、《Spring技术内幕:深入解析Spring架构与设计原理(第2版)》
书接上回,在上篇 第四十三章 Spring之假如让你来写MVC——上传文件篇 中,A君 已经完成了文件上传部分的功能了。接下来看看 A君 会有什么骚操作吧
尝试动手写IOC容器
出场人物:A君(苦逼的开发)、老大(项目经理)
背景:老大 要求 A君在一周内开发个简单的 IOC容器
前情提要:A君 已经完成了文件上传部分的功能了 。。。
第三十八版 异常处理
“干得好!A君,现在万里长征只剩下最后几步了,今天在添加个 异常处理器 !” 老大 眼睛都快眯成缝了
“异常处理器 ?这个怎么说?” A君 疑惑道
老大 神色一敛,语重心长的说道:“简单,就像请求过程中出现异常了,要怎么办?HTTP规定了一堆的响应码,要根据异常返回对应的响应码。还有你看现在网站的错误页面,错误页面一般情况下是不会直接暴露给用户看的,一来对用户来说,这种页面没意义,你只需要告诉用户要怎么做就行了。二来对于有心人来说,这些信息很可能被利用,造成安全方面的问题。所以异常这部分内容还是很重要的。” 说完,老大 看向 A君 “怎么样?心里有思路了吗?”
A君 略一沉吟,开口说道:“这块内容应该和之前的参数解析,视图定位的内容差不多的,需要根据 控制器 抛出的异常进行处理,用户可以配置各个异常以及对应页面,出现异常时,我们只需要根据异常信息来找到对应的页面即可!”
老大 露出一丝赞许的表情,笑着说道:“哈哈!A君 你现在成长了不少哩。对!整体思路确实是这样子的,既然你已经明白了,我就不在多说什么了,你去做做看吧!”
异常处理器
A君 从办公室出来后,就开始着手撸代码了。毕竟牛皮也吹出去了,要赶紧做出来才行。当务之急还是先设计个接口。A君 定义HandlerExceptionResolver
接口,用以处理 控制器 出现的异常。代码如下:
/**
* 异常处理
*/
public interface HandlerExceptionResolver {
ModelAndView resolveException(
HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex);
}
接口好了,老样子,接下来就是抽象类,可以异常处理有什么共同点的呢?A君 一阵挠头。想了半天,A君 也没想出个所以然来。既然没什么共同点,那就校验吧。检验是否包含对应的 异常处理器 总不会错吧。思量完毕,A君 定义AbstractHandlerExceptionResolver
类。代码如下:
public abstract class AbstractHandlerExceptionResolver implements HandlerExceptionResolver, Ordered {
private static final String HEADER_CACHE_CONTROL = "Cache-Control";
private int order = Ordered.LOWEST_PRECEDENCE;
private Set<?> mappedHandlers;
private Class<?>[] mappedHandlerClasses;
private boolean preventResponseCaching = false;
@Override
public ModelAndView resolveException(
HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
/**
* 寻找匹配的处理器
*/
if (shouldApplyTo(request, handler)) {
//禁止缓存
prepareResponse(ex, response);
return doResolveException(request, response, handler, ex);
} else {
return null;
}
}
/**
* 寻找匹配的处理器
*/
protected boolean shouldApplyTo(HttpServletRequest request, Object handler) {
if (handler != null) {
if (this.mappedHandlers != null && this.mappedHandlers.contains(handler)) {
return true;
}
if (this.mappedHandlerClasses != null) {
for (Class<?> handlerClass : this.mappedHandlerClasses) {
if (handlerClass.isInstance(handler)) {
return true;
}
}
}
}
return !hasHandlerMappings();
}
/**
* 注册处理器
*/
protected boolean hasHandlerMappings() {
return (this.mappedHandlers != null || this.mappedHandlerClasses != null);
}
protected void prepareResponse(Exception ex, HttpServletResponse response) {
if (this.preventResponseCaching) {
preven