没有合适的资源?快使用搜索试试~ 我知道了~
02-01-08-用30个类高仿真提炼纯手写Spring框架V2.0之MVC1
需积分: 0 1 下载量 115 浏览量
2022-08-04
16:51:28
上传
评论
收藏 578KB PDF 举报
温馨提示
试读
21页
02-01-08-用30个类高仿真提炼纯手写Spring框架V2.0之MVC1
资源详情
资源评论
资源推荐
咕泡出品,必属精品 www.gupaoedu.com
1
课程目标
1、高仿真手写 Spring MVC 部分,充分实践设计模式。
2、用 30 个类搭建基本框架,满足核心功能。
内容定位
在完全掌握 Spring 系统结构、实现原理,在理解设计模式的基础上,自己动手写一个高仿真版本的
Spring 框架,以达到透彻理解 Spring 的目的,感受作者创作意图。
MVC 顶层设计
GPDispatcherServlet
package com.gupaoedu.vip.spring.formework.webmvc.servlet;
import com.gupaoedu.vip.spring.formework.annotation.GPController;
import com.gupaoedu.vip.spring.formework.annotation.GPRequestMapping;
import com.gupaoedu.vip.spring.formework.context.GPApplicationContext;
import com.gupaoedu.vip.spring.formework.webmvc.*;
import lombok.extern.slf4j.Slf4j;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
咕泡出品,必属精品 www.gupaoedu.com
2
* Created by Tom.
*/
//Servlet 只是作为一个 MVC 的启动入口
@Slf4j
public class GPDispatcherServlet extends HttpServlet {
private final String LOCATION = "contextConfigLocation";
//课后再去思考一下这样设计的经典之处
//GPHandlerMapping 最核心的设计,也是最经典的
//它牛 B 到直接干掉了 Struts、Webwork 等 MVC 框架
private List<GPHandlerMapping> handlerMappings = new ArrayList<GPHandlerMapping>();
private Map<GPHandlerMapping,GPHandlerAdapter> handlerAdapters = new HashMap<GPHandlerMapping,
GPHandlerAdapter>();
private List<GPViewResolver> viewResolvers = new ArrayList<GPViewResolver>();
private GPApplicationContext context;
@Override
public void init(ServletConfig config) throws ServletException {
//相当于把 IOC 容器初始化了
context = new GPApplicationContext(config.getInitParameter(LOCATION));
initStrategies(context);
}
protected void initStrategies(GPApplicationContext context) {
//有九种策略
// 针对于每个用户请求,都会经过一些处理的策略之后,最终才能有结果输出
// 每种策略可以自定义干预,但是最终的结果都是一致
// ============= 这里说的就是传说中的九大组件 ================
initMultipartResolver(context);//文件上传解析,如果请求类型是 multipart 将通过
MultipartResolver 进行文件上传解析
initLocaleResolver(context);//本地化解析
initThemeResolver(context);//主题解析
/**
我们自己会实现
*/
//GPHandlerMapping 用来保存 Controller 中配置的 RequestMapping 和 Method 的一个对应关系
initHandlerMappings(context);//通过 HandlerMapping,将请求映射到处理器
/**
我们自己会实现
*/
//HandlerAdapters 用来动态匹配 Method 参数,包括类转换,动态赋值
咕泡出品,必属精品 www.gupaoedu.com
3
initHandlerAdapters(context);//通过 HandlerAdapter 进行多类型的参数动态匹配
initHandlerExceptionResolvers(context);//如果执行过程中遇到异常,将交给
HandlerExceptionResolver 来解析
initRequestToViewNameTranslator(context);//直接解析请求到视图名
/**
我们自己会实现
*/
//通过 ViewResolvers 实现动态模板的解析
//自己解析一套模板语言
initViewResolvers(context);//通过 viewResolver 解析逻辑视图到具体视图实现
initFlashMapManager(context);//flash 映射管理器
}
private void initFlashMapManager(GPApplicationContext context) {}
private void initRequestToViewNameTranslator(GPApplicationContext context) {}
private void initHandlerExceptionResolvers(GPApplicationContext context) {}
private void initThemeResolver(GPApplicationContext context) {}
private void initLocaleResolver(GPApplicationContext context) {}
private void initMultipartResolver(GPApplicationContext context) {}
//将 Controller 中配置的 RequestMapping 和 Method 进行一一对应
private void initHandlerMappings(GPApplicationContext context) {
//按照我们通常的理解应该是一个 Map
//Map<String,Method> map;
//map.put(url,Method)
//首先从容器中取到所有的实例
String [] beanNames = context.getBeanDefinitionNames();
try {
for (String beanName : beanNames) {
//到了 MVC 层,对外提供的方法只有一个 getBean 方法
//返回的对象不是 BeanWrapper,怎么办?
Object controller = context.getBean(beanName);
//Object controller = GPAopUtils.getTargetObject(proxy);
Class<?> clazz = controller.getClass();
if (!clazz.isAnnotationPresent(GPController.class)) {
continue;
}
咕泡出品,必属精品 www.gupaoedu.com
4
String baseUrl = "";
if (clazz.isAnnotationPresent(GPRequestMapping.class)) {
GPRequestMapping requestMapping = clazz.getAnnotation(GPRequestMapping.class);
baseUrl = requestMapping.value();
}
//扫描所有的 public 方法
Method[] methods = clazz.getMethods();
for (Method method : methods) {
if (!method.isAnnotationPresent(GPRequestMapping.class)) {
continue;
}
GPRequestMapping requestMapping = method.getAnnotation(GPRequestMapping.class);
String regex = ("/" + baseUrl + requestMapping.value().replaceAll("\\*",
".*")).replaceAll("/+", "/");
Pattern pattern = Pattern.compile(regex);
this.handlerMappings.add(new GPHandlerMapping(pattern, controller, method));
log.info("Mapping: " + regex + " , " + method);
}
}
}catch (Exception e){
e.printStackTrace();
}
}
private void initHandlerAdapters(GPApplicationContext context) {
//在初始化阶段,我们能做的就是,将这些参数的名字或者类型按一定的顺序保存下来
//因为后面用反射调用的时候,传的形参是一个数组
//可以通过记录这些参数的位置 index,挨个从数组中填值,这样的话,就和参数的顺序无关了
for (GPHandlerMapping handlerMapping : this.handlerMappings){
// //每一个方法有一个参数列表,那么这里保存的是形参列表
this.handlerAdapters.put(handlerMapping,new GPHandlerAdapter());
}
}
private void initViewResolvers(GPApplicationContext context) {
//在页面敲一个 http://localhost/first.html
咕泡出品,必属精品 www.gupaoedu.com
5
//解决页面名字和模板文件关联的问题
String templateRoot = context.getConfig().getProperty("templateRoot");
String templateRootPath =
this.getClass().getClassLoader().getResource(templateRoot).getFile();
File templateRootDir = new File(templateRootPath);
for (File template : templateRootDir.listFiles()) {
this.viewResolvers.add(new GPViewResolver(templateRoot));
}
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException,
IOException {
this.doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException,
IOException {
try {
doDispatch(req, resp);
}catch (Exception e){
resp.getWriter().write("<font size='25' color='blue'>500
Exception</font><br/>Details:<br/>" + Arrays.toString(e.getStackTrace()).replaceAll("\\[|\\]","")
.replaceAll("\\s","\r\n") + "<font
color='green'><i>Copyright@GupaoEDU</i></font>");
e.printStackTrace();
}
}
private void doDispatch(HttpServletRequest req, HttpServletResponse resp) throws Exception{
//根据用户请求的 URL 来获得一个 Handler
GPHandlerMapping handler = getHandler(req);
if(handler == null){
processDispatchResult(req,resp,new GPModelAndView("404"));
return;
}
剩余20页未读,继续阅读
H等等H
- 粉丝: 34
- 资源: 337
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- 三层独栋别墅图纸编号D066-三层-12.00&12.00米- 施工图.dwg
- 农村小别墅图纸编号D065-三层-14.40&18.55米-施工图.dwg
- 基于YOLOv8检测高铁吊弦缺陷实现的系统的Python源码+文档说明+训练源文件+模型.zip
- 三层农村小别墅图纸编号D064-三层-13.80&22.20米-施工图.dwg
- 三层别墅图纸编号D063-三层-13.57&17.40米- 施工图.dwg
- STC IAP15F2K61S2单片机i2c 接口PCF8591-ADC实验+DAC实验 KEIL例程源码+开发板硬件原理图
- Jlink-windows-v7967
- ADC直流分量影响分析
- 二层半独栋别墅结构水电施工图结构专家电.dwg
- 二层半独栋别墅结构水电施工图结构水暖图.dwg
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
评论0