简单的手写springmvc思路

简单的手写springmvc思路

首先,做一个简单的思考,mvc的概念是什么样的。springmvc实现了一个什么样的功能(当然,咱们不能面面俱到,只是一个简单的臆想…)

其次,技术上要用到什么,需要考虑哪方面的知识。

最后, 整个过程是依赖servlet 来完成的。

这次只探讨springmvc大致的实现过程,从请求到映射的过程。其他优秀的地方暂时不在考虑的范围之内

mvc

MVC是三个单词的首字母缩写,它们是Model(模型)、View(视图)和Controller(控制)。

在这里插入图片描述

图片来源:菜鸟教程

具体的模型 或者 认知 建议自己百度一下。

springmvc

谈到springMVC,咱们不得不提到一个大管家DispatcherServlet 这个类在spring里面是继承自 FrameworkServlet,里面实现了ApplicationContextAware接口并继承了HttpServlet。具体的实现和作用暂时不在谈论范围之内。

在这里插入图片描述

图片来源:https://www.cnblogs.com/hamawep789/p/10840774.html

具体的网上也有很多类似的介绍springmvc 执行流程这一系列,在这暂不做介绍

知识点(技术性分析)

在此之前,我想说明一下,今咱们只是简单的分析一下,只要是从发送请求到接受,到处理映射 再到返回。这么一个过程。

在这里插入图片描述

大致流程:

在tomcat启动的时候执行初始化。

  • 参照spring,自定义一个实例化类的Map.存放已经实例化好的Controller、service等(ioc)
  • 参照spring DI 属性注入
  • 参照处理器映射器,自定义一个映射器Map handlerMap 存放路径映射对应的controller+方法。
  • 参照处理器适配器,在反射的时候根据不同的参数,有不同的处理。1)if …else if 判断 2)策略模式。

所有的前提都是在正确的把编译好的.class 文件读到内存中,在实例化之前。

细节分析

上面所讲的初始化 都应该在容器启动之前都初始化完毕。有两种方式可行

初始化
  1. 遵守servlet3.0规范,在类路径下 新建 META-INF\services\javax.servlet.ServletContainerInitializer 这样一个文件。里面写上一个接口,在容器启动的时候会自动扫描实现这个接口的实现类

例如 springmvc中是实现这个: org.springframework.web.SpringServletContainerInitializer

@HandlesTypes(WebApplicationInitializer.class)
public class SpringServletContainerInitializer implements ServletContainerInitializer {

	
	@Override
	public void onStartup(Set<Class<?>> webAppInitializerClasses, ServletContext servletContext)
			throws ServletException {

		List<WebApplicationInitializer> initializers = new LinkedList<WebApplicationInitializer>();

		if (webAppInitializerClasses != null) {
			for (Class<?> waiClass : webAppInitializerClasses) {
				// Be defensive: Some servlet containers provide us with invalid classes,
				// no matter what @HandlesTypes says...
				if (!waiClass.isInterface() && !Modifier.isAbstract(waiClass.getModifiers()) &&
						WebApplicationInitializer.class.isAssignableFrom(waiClass)) {
					try {
						initializers.add((WebApplicationInitializer) waiClass.newInstance());
					}
					catch (Throwable ex) {
						throw new ServletException("Failed to instantiate WebApplicationInitializer class", ex);
					}
				}
			}
		}

		if (initializers.isEmpty()) {
			servletContext.log("No Spring WebApplicationInitializer types detected on classpath");
			return;
		}

		servletContext.log(initializers.size() + " Spring WebApplicationInitializers detected on classpath");
		AnnotationAwareOrderComparator.sort(initializers);
		for (WebApplicationInitializer initializer : initializers) {
			initializer.onStartup(servletContext);
		}
	}

}

在这里插入图片描述
在这里插入图片描述

具体不是今天分析的重点,可以自己去百度看看。其实跟spring 中IOC 一个模样。会自动把先加载的类事先实例化。

  1. 新建DispatcherServlet 继承 HttpServlet 实现init() 方法。配合web.xml 实现自动加载。
实现DI 时需要注意

在咱们开发的时候一般都是

// @Autowired
@Resource("XXX")
private XXService service;

**因为是基于反射去做,在获取到 私有属性的时候 需要 field.setAccessible(true) 把私有属性放开 **

这也就是说为什么不安全的地方。哈哈

处理器适配器

映射器简单,就是一个map key — vue 对应 /user/getById(key) ------- getById() 方法(value)

这里的适配器,只要是针对不同的请求参数做解析处理的所以需要做特殊处理。 最后把参数数据返回 method.invoke()执行就可以。

总结

好了,到这里也就阐述完毕,其实多想想很简单这个东西。就是 自定义注解、反射、可能还会涉及到IO的知识,就这些了。

这只是仅仅代表我个人的拙见,如果有什么不对的请指正,谢谢。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值