spring mvc的处理流程

一、在web.xml中配置DispatcherServlet(实现了Servlet接口)的相关信息,其中包括:

      1、初始化参数init-param的name、value(contextConfigLocation: 配置文件的路径)

      2、Servlet处理的请求映射url (servlet-mapping)

 

二、在DispatcherServlet的初始化方法init()中做如下处理(Tomcat是Servlet容器,启动Tomcat会加载Servlet并初始化)

      1、加载配置文件

//获取配置文件路径(servletConfig为init()的入参)
String contextConfigLocation = servletConfig.getInitParameter("contextConfigLocation");

//获取文件输入流(this是DispatcherServlet对象)
InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(contextConfigLocation);

//使用Properties读取输入流
Properties contextConfig = new Properties();
contextConfig.load(inputStream);

//获取配置信息,此处举例为:扫描包的路径
contextConfig.getProperty("scan-package");

      2、将扫描包路径下的所有类名存入List<String>中

URL resourcePath = this.getClass().getClassLoader().getResource("scan-path");

File scanPath = new File(resourcePath.getFile());

//递归获取文件名并过滤.class文件以外的文件,保存类名(全限定名)
List<String> classNameList = new ArrayList<>();
classNameList.add(className);

      3、将加有@Controller/@Service等注解的类的对象放入ioc容器中(利用java反射机制,生成对象)

Map<String, Object> iocMap = new HashMap<>();
Class<?> clazz = Class.forName(className);
if (clazz.isAnnotationPresent(Controller.class)) {
    Object instance = clazz.newInstance();
    iocMap.put(beanName, instance);
}
//如果有实现接口的(如Service),需要把接口名及对应的实例引用放入ioc容器中(clazz.getInterfaces())

      4、将加有@Autowired注解的属性成员赋值(通过java反射机制,完成注入)

//获取字段(instance为ioc容器中的对象)
Field[] fields = instance.getClass().getDeclaredFields();

//获取注解类型名称
String beanName = field.getType().getName();

//将字段设置为可访问的
field.setAccessible(true);

//设置字段的值,完成注入
field.set(instance, iocMap.get(beanName));

    5、将Controller中加有@RequestMapping注解的方法缓存起来(通过java反射机制,获得方法)

//缓存容器
Map<String, Method> urlMethodMapping = new HashMap<>();

//instance为ioc容器中的对象
Class<?> clazz = instance.getClass();

//获取类RequestMapping路径
if(clazz.isAnnotationPresent(Controller.class) && clazz.isAnnotationPresent(RequestMapping.class)) {
    RequestMapping requestMapping = clazz.getAnnotation(RequestMapping.class);
    String baseUrl = RequestMapping.value();
}

//获取方法RequestMapping路径
if (method.isAnnotationPresent(RequestMapping.class)) {
    String methodUrl = method.getAnnotation(RequestMapping.class).value();
}

//缓存方法
urlMethodMapping.put(url, method);

 

三、在Servlet的doGet()和doPost()中,将请求的url与缓存的urlMethodMapping比对,并调用请求的方法。(反射机制)

//HttpServletRequest、HttpServletResponse是doPost/doGet的入参
String url = reqest.getRequestURI();

//获取缓存的方法
Method method = this.urlMethodMapping.get(url);

//取得方法对应的类型,并从ioc容器中获取对象,再调用方法
String beanName = method.getDeclaringClass().getSimpleName();
method.invoke(iocMap.get(beanName), reqest, response);

 

在此感谢下面这篇博客和这本书,我才对springmvc的流程有了大概的了解。

博客:https://blog.csdn.net/qq_40147863/article/details/96505433

书籍:《Spring 5核心原理与30个类手写实战》

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值