【学习笔记】手写一个简单的 Spring MVC

目录

一、什么是Spring MVC ?

Spring 和 Spring MVC 的区别?

Spring MVC 的运行流程?

二、实现步骤

1. DispatcherServlet

1. 创建一个中央分发器

拦截所有请求

测试

2. 接管 IOC 容器

1. 创建配置文件

2. 修改 web.xml 配置文件

3. 启动 IOC 容器

2. HandlerMapping

1. 添加映射

1. 创建 RequestMapping 注解

2. 创建映射Bean

3. 使用 RequestMapping 注解

4. 添加映射

2. 处理映射

1. 创建 ResponseBody 注解

2. 创建一个 HTML 文件

3. 使用 ResponseBody 注解

4. 处理映射

3. 测试


一、什么是Spring MVC ?

Spring MVC 是 Spring 的模块之一,Spring MVC 实现了MVC 的设计思想,并继承了 Servlet API 的WEB 框架。当用户在游览器地址栏上输入 url 后,Spring MVC就可以处理用户的请求

Spring 和 Spring MVC 的区别?

Spring 是一个框架,这个框架由不同的模块组成,其中一个模块 就是Spring MVC,Spring 核心是IOC 控制反转,IOC 容器负责对象的创建和依赖注入。

Spring MVC 是基于 MVC 设计来开发web 应用,Spring MVC 将前端发送的请求分发给适当的控制器 Controller,然后根据结果选择合适的视图进行渲染返回

Spring MVC 的运行流程?

  1. 用户发送HTTP请求
  2. 请求到达服务器后,Spring MVC 的中央分发器拦截请求
  3. 中央分发器根据 请求的路径找到对应的 HandlerMapping,确定由哪个 Controller 控制器处理
  4. HandlerMaping 根据请求信息映射到对应的 Controller ,然后返回给中央分发器
  5. 中央分发器把请求交给对应的Controller 控制器,Controller 是Spring MVC的一个组件,它负责处理请求以及响应结果
  6. Controller 控制器调用合适的业务层或 Mapper 层获取数据
  7. Controller 把数据封装成一个ModelAndView对象,然后返回给中央分发器
  8. 中央分发器把ModelAndView对象传给 ViewResolver
  9. ViewResolver 根据视图名称解析出一个 View 对象,然后返回给中央分发器
  10. 中央分发器把 view 对象渲染出来返回给客户端

在 手写 Spring IOC 的基础上再进行扩展,手写一个 Spring MVC

二、实现步骤

1. DispatcherServlet

1. 创建一个中央分发器

package com.shao.MVC;

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.IOException;


public class DispatcherServlet extends HttpServlet {

    @Override
    public void init(ServletConfig config) throws ServletException {
        System.out.println("dispatcherServlet 初始化");
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("dispatcherServlet 开始执行任务了");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("dispatcherServlet doPost");
    }

}

拦截所有请求

在 Tomcat 的 web.xml 配置文件中配置自定义的中央分发器,拦截所有请求

<!DOCTYPE web-app PUBLIC
        "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
        "http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
    <display-name>Archetype Created Web Application</display-name>
    <servlet>
        <servlet-name>dispatcherServlet</servlet-name>
        <servlet-class>com.shao.MVC.DispatcherServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>dispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

</web-app>

测试

在地址栏随便输入一个请求,中央分发器会进行拦截,然后执行初始化和相关方法,初始化只会执行一次

2. 接管 IOC 容器

在 手写 spring IOC 的时候,为了方便测试是在 Servlet 的 doGet 方法中初始化 IOC 容器,现在改为在中央分发器初始化的时候启动 IOC 容器

1. 创建配置文件

在配置文件中配置扫描包路径,然后启动中央分发器的时候把配置文件传过去

2. 修改 web.xml 配置文件

3. 启动 IOC 容器

在中央分发器的初始化方法中启动 IOC 容器

package com.shao.MVC;

import com.shao.IOC.ApplicationContext;

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.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.Properties;


public class DispatcherServlet extends HttpServlet {

    // 存储 IOC 容器
    private ApplicationContext applicationContext;
    private Properties Prop = new Properties();

    /**
     * 初始化
     */
    @Override
    public void init(ServletConfig config) throws ServletException {
        System.out.println("dispatcherServlet 初始化");
        // 获取传过来的配置文件
        String configLocation = config.getInitParameter("contextConfigLocation");
        String fileName = configLocation.replace("classpath:", "");
        // 调用 loadConfig 方法,传入配置文件名,返回扫描包路径
        String packagePath = loadConfig(fileName);

        try {
            // 启动 IOC 容器
            applicationContext = new ApplicationContext(packagePath);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("dispatcherServlet 开始执行任务了");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("dispatcherServlet doPost");
    }

    /**
     * 加载配置文件,解析配置文件,返回扫描包路径
     */
    public String loadConfig(String path) {

        // 以流的方式加载配置文件
        InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream(path);

        String basePackage = "";
        try {
            // 解析配置文件中的属性,以键值对的方式存储到 Prop 中
            Prop.load(resourceAsStream);
            basePackage = Prop.getProperty("basePackage");

        } catch (IOException e) {
            e.printStackTrace();
        }
        return basePackage;
    }

}

2. HandlerMapping

HandlerMapping 根据注解的值映射到对应的 Controller 和方法

将 url 和 controller 里面的方法进行映射,存到 HashMap 中,key 是 url ,value 是一个对象,这个对象有 url 对应的 controller 对象和对应的方法

1. 添加映射

1. 创建 RequestMapping 注解

2. 创建映射Bean

package com.shao.MVC;


import java.lang.reflect.Method;

public class RequestMappingBean {
    /**
     * controller 对象
     */
    private Object controller;
    /**
     * controller 的方法
     */
    private Method method;

    public RequestMappingBean(Object controller, Method method) {
        this.controller = controller;
        this.method = method;
    }

    /**
     * 获取
     *
     * @return controller
     */
    public Object getController() {
        return controller;
    }

    /**
     * 设置
     *
     * @param controller
     */
    public void setController(Object controller) {
        this.controller = controller;
    }

    /**
     * 获取
     *
     * @return method
     */
    public Method getMethod() {
        return method;
    }

    /**
     * 设置
     *
     * @param method
     */
    public void setMethod(Method method) {
        this.method = method;
    }

    public String toString() {
        return "RequestMappingBean{controller = " + controller + ", method = " + method + "}";
    }
}

3. 使用 RequestMapping 注解

4. 添加映射
package com.shao.MVC;

import com.shao.Annotation.Controller;
import com.shao.Annotation.RequestMapping;
import com.shao.IOC.ApplicationContext;

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.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Properties;


public class DispatcherServlet extends HttpServlet {

    // 存储 IOC 容器
    private ApplicationContext applicationContext;
    private Properties Prop = new Properties();

    private HashMap<String, RequestMappingBean> mappingMap = new HashMap<>();


    /**
     * 初始化
     */
    @Override
    public void init(ServletConfig config) throws ServletException {
        System.out.println("dispatcherServlet 初始化");
        // 获取传过来的配置文件
        String configLocation = config.getInitParameter("contextConfigLocation");
        String fileName = configLocation.replace("classpath:", "");
        // 调用 loadConfig 方法,传入配置文件名,返回扫描包路径
        String packagePath = loadConfig(fileName);

        try {
            // 启动 IOC 容器
            applicationContext = new ApplicationContext(packagePath);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        // 添加映射
        AddRequestMapping();
        
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("dispatcherServlet 开始执行任务了");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("dispatcherServlet doPost");
    }

    /**
     * 加载配置文件,解析配置文件,返回扫描包路径
     */
    public String loadConfig(String path) {

        // 以流的方式加载配置文件
        InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream(path);

        String basePackage = "";
        try {
            // 解析配置文件中的属性,以键值对的方式存储到 Prop 中
            Prop.load(resourceAsStream);
            basePackage = Prop.getProperty("basePackage");

        } catch (IOException e) {
            e.printStackTrace();
        }
        return basePackage;
    }

    /**
     * 添加映射
     * 1. 从 IOC 容器中获取所有带 RequestMapping 注解的 Controller 对象
     * 2. 获取 Controller 对象中带 RequestMapping 注解的方法
     * 3. 将 Controller 对象和方法封装为 RequestMappingBean 对象
     * 4. 构建映射关系,key 是 url,value 是 映射Bean 对象,包括 Controller 对象和方法
     */

    public void AddRequestMapping() {
        // 获取 IOC 容器的 Bean Map
        HashMap<String, Object> beanMap = applicationContext.getBeanMap();

        for (Object bean : beanMap.values()) {
            // 获取 bean 的 Class 对象
            Class<?> aClass = bean.getClass();

            // 判断是否有 @Controller 注解
            if (!aClass.isAnnotationPresent(Controller.class)) {
                continue;
            }

            // 判断是否有 @RequestMapping 注解
            if (!aClass.isAnnotationPresent(RequestMapping.class)) {
                continue;
            }

            // 获取类的 @RequestMapping 注解的值
            String basePath = aClass.getAnnotation(RequestMapping.class).value();

            // 获取 Controller 对象中的所有方法
            Method[] methods = aClass.getDeclaredMethods();
            for (Method method : methods) {

                // 判断方法上有没有带 @RequestMapping 注解
                if (!method.isAnnotationPresent(RequestMapping.class)) {
                    continue;
                }
                String path = method.getAnnotation(RequestMapping.class).value();

                // 封装为 映射Bean 对象
                RequestMappingBean mappingBean = new RequestMappingBean(bean, method);

                // 构建映射,添加到 Map 中
                mappingMap.put(basePath + path, mappingBean);
            }
        }

        System.out.println("映射添加完成");
        System.out.println(mappingMap);

    }

}

2. 处理映射

1. 创建 ResponseBody 注解

2. 创建一个 HTML 文件

3. 使用 ResponseBody 注解

4. 处理映射

为了方便测试,只处理了 GET 方法的映射

package com.shao.MVC;

import com.alibaba.fastjson2.JSON;
import com.shao.Annotation.Controller;
import com.shao.Annotation.RequestMapping;
import com.shao.Annotation.ResponseBody;
import com.shao.IOC.ApplicationContext;

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.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Method;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Properties;


public class DispatcherServlet extends HttpServlet {

    // 存储 IOC 容器
    private ApplicationContext applicationContext;
    private Properties Prop = new Properties();

    private HashMap<String, RequestMappingBean> mappingMap = new HashMap<>();


    /**
     * 初始化
     */
    @Override
    public void init(ServletConfig config) throws ServletException {
        System.out.println("dispatcherServlet 初始化");
        // 获取传过来的配置文件
        String configLocation = config.getInitParameter("contextConfigLocation");
        String fileName = configLocation.replace("classpath:", "");
        // 调用 loadConfig 方法,传入配置文件名,返回扫描包路径
        String packagePath = loadConfig(fileName);

        try {
            // 启动 IOC 容器
            applicationContext = new ApplicationContext(packagePath);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        // 添加映射
        AddRequestMapping();

    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("dispatcherServlet 开始执行任务了");

        // 处理请求
        HandlerMapping(req, resp);

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("dispatcherServlet doPost");
    }

    /**
     * 加载配置文件,解析配置文件,返回扫描包路径
     */
    public String loadConfig(String path) {

        // 以流的方式加载配置文件
        InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream(path);

        String basePackage = "";
        try {
            // 解析配置文件中的属性,以键值对的方式存储到 Prop 中
            Prop.load(resourceAsStream);
            basePackage = Prop.getProperty("basePackage");

        } catch (IOException e) {
            e.printStackTrace();
        }
        return basePackage;
    }

    /**
     * 添加映射
     * 1. 从 IOC 容器中获取所有带 RequestMapping 注解的 Controller 对象
     * 2. 获取 Controller 对象中带 RequestMapping 注解的方法
     * 3. 将 Controller 对象和方法封装为 RequestMappingBean 对象
     * 4. 构建映射关系,key 是 url,value 是 映射Bean 对象,包括 Controller 对象和方法
     */

    public void AddRequestMapping() {
        // 获取 IOC 容器的 Bean Map
        HashMap<String, Object> beanMap = applicationContext.getBeanMap();

        for (Object bean : beanMap.values()) {
            // 获取 bean 的 Class 对象
            Class<?> aClass = bean.getClass();

            // 判断是否有 @Controller 注解
            if (!aClass.isAnnotationPresent(Controller.class)) {
                continue;
            }

            // 判断是否有 @RequestMapping 注解
            if (!aClass.isAnnotationPresent(RequestMapping.class)) {
                continue;
            }

            // 获取类的 @RequestMapping 注解的值
            String basePath = aClass.getAnnotation(RequestMapping.class).value();

            // 获取 Controller 对象中的所有方法
            Method[] methods = aClass.getDeclaredMethods();
            for (Method method : methods) {

                // 判断方法上有没有带 @RequestMapping 注解
                if (!method.isAnnotationPresent(RequestMapping.class)) {
                    continue;
                }
                String path = method.getAnnotation(RequestMapping.class).value();

                // 封装为 映射Bean 对象
                RequestMappingBean mappingBean = new RequestMappingBean(bean, method);

                // 构建映射,添加到 Map 中
                mappingMap.put(basePath + path, mappingBean);
            }
        }

        System.out.println("映射添加完成");
        System.out.println(mappingMap);

    }

    /**
     * 处理请求,根据 url 找到对应的映射对象,调用对应的方法,返回结果
     */
    public void HandlerMapping(HttpServletRequest req, HttpServletResponse resp) throws IOException {

        // 获取请求的路径,这个请求路径中有项目名称
        String requestURI = req.getRequestURI();
        // 获取项目名
        String contextPath = req.getContextPath();
        // 去掉项目名
        String url = requestURI.replace(contextPath, "");

        // 获取 url 对应的映射对象
        RequestMappingBean mappingBean = mappingMap.get(url);
        Object controller = mappingBean.getController();
        Method method = mappingBean.getMethod();
        Object res = null;
        try {
            // 调用映射对象中的方法
            res = method.invoke(controller);
        } catch (Exception e) {
            e.printStackTrace();
        }

        // 判断方法是否有返回内容
        if (res == null) {
            return;
        }

        // 判断方法是否有 @ResponseBody 注解
        if (method.isAnnotationPresent(ResponseBody.class)) {
            resp.setContentType("application/json;charset=utf-8");

            // 响应数据
            resp.getWriter().write(JSON.toJSONString(res));

        } else {

            // 获取编译后的项目根目录
            String path = this.getClass().getClassLoader().getResource("../../").getPath();

            // 路径前面有一个 /,比如: /D:/xxx,需要去掉,然后拼接静态资源名称
            String filePath = path.substring(1) + res;

            try {
                // 解码,如果路径有空格或者中文,会出现 16 进制的字符
                filePath = URLDecoder.decode(filePath, "UTF-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }

            // 获取静态资源内容
            byte[] fileContents = StaticResourceHandler.getFileContents(filePath);
            // 获取文件媒体类型
            String mimeType = StaticResourceHandler.getFileMimeType(filePath);
            resp.setContentType(mimeType + ";charset=utf-8");

            // 响应内容
            resp.getWriter().write(new String(fileContents));
        }
    }
}

3. 测试

如果显示乱码可以添加以下命令试一下

-Dfile.encoding=UTF-8

手写Spring框架之MVC 简介 手写Spring框架第一篇博客(必读): 手写Spring框架 上一篇博客实现了Bean容器和IOC功能, 本篇博客来实现简化版的 Spring MVC. 在看下面的内容之前, 我们首先来回顾下 Spring MVC的架构图: Spring MVC 最核心部分的就是前端控制器DispatcherServlet, 而DispatcherServlet其实就是一个Servlet, 所以我们有必... 阅读详情

相关推荐

Spring MVC 一个简单的多文件上传

Spring解析文件到MultipartFile数组。返回'success'

xiaoyu070321的博客 1301

手写SSM(SpringMvc+Spring+MyBatis)框架源码

 Java框架一直以来都是面试的重要知识点,而学习Java框架,不管在成熟的大公司,快速发展的公司,还是创业阶段的公司,都能对当前正在开发中的系统有整体的认知,从而更好的熟悉和学习技术。 本教程以项目实战为导向,帮助广大学员细心教学,本课程从无到有,循序渐进的手写SSM(SpringMvc+Spring+MyBatis)框架,由于官方的框架比较复杂,为了让同学们能够学懂,先从简单地框架入手,然后不断地升级和迭代,逐渐成为官方比较接近的SSM框架。希望同学们通过我的课程学习,能成为自己手动编写框架的高手,深化框架的使用,同时积累一定的代码量,在公司成为顶梁柱。助你更能深刻的理解SSM(SpringMvc+Spring+MyBatis)框架的原理!! 源码截图: 

【Spring Boot原理】假设我们要创建一个简单的Spring Boot应用,使用Spring MVC来处理HTTP请求Spring MVC是一个用于构建Web应用的框架,它是Spring框架的一

Spring Boot通过自动配置和起步依赖简化了Spring应用的配置和启动过程,使得开发者可以更快地开始编码。而Spring MVC提供了一个灵活的Web应用框架,通过MVC模式将应用的不同部分分离,提高了代码的可维护性和可测试性。两者的结合为Java Web开发提供了强大的支持,使得开发者可以专注于业务逻辑的实现,而无需担心底层的技术细节。学习教程(传送门)1、掌握JAVA入门到进阶知识(持续写作中……2、学会Oracle数据库用法(创作中……3、手把手教你vbs脚本制作(

王大师企业官方博客 3466

手把手教你手写Spring框架(附源码)

  Java框架一直以来都是面试必备的知识点,而学习Java框架,不管在成熟的大公司,快速发展的公司,还是创业阶段的公司,都能对当前正在开发中的系统有整体的认知,从而更好的熟悉和学习技术。 本教程以项目实战为导向,帮助广大学员手把手教学,本课程从无到有,循序渐进的手写mvc框架,由于官方的框架比较复杂,为了让同学们能够学懂,先从简单地IOC框架入手,然后不断地升级和迭代,逐渐成为官方比较接近的Spring框架。希望同学们通过我的课程学习,能成为自己手动编写框架的高手,深化框架的使用,同时积累一定的代码量,在公司成为顶梁柱。 项目工程截图:    

山东专升本计算机网络基础知识点 --- 计算机网络基础

计算机网络是指将一群具有独立\textcolor{WildStrawberry}{独立}独立功能的计算机通过通信设备及传输媒体等互联起来,在通信软件的支持下,实现计算机间资源共享、信息交换或协同工作\textcolor{WildStrawberry}{资源共享、信息交换或协同工作}资源共享、信息交换或协同工作的系统。计算机网络是计算机技术和通信技术紧密结合的产物\textcolor{WildStrawberry}{计算机网络是计算机技术和通信技术紧密结合的产物}

z339521的博客 2814

2023-10-20 - MacBook - 优化外接2k显示器体验:告别字小与字虚的终极指南

本文针对MacBook外接2K显示器时普遍遇到的字体过小和边缘发虚问题,提供了终极解决方案。通过深入解析macOS的HiDPI与Retina显示原理,并详细指导使用SwitchResX等工具开启隐藏的HiDPI模式,实现完美的2倍整数缩放,从而在保证字体大小合适的同时获得清晰锐利的显示效果,彻底告别字小与字虚的困扰。

solidity8miner的博客 476

手写简易版SpringMVC(避免死记硬背八股文)

1.在把一个``JavaWeb``程序打成``war``包丢入``Tomcat``后,当启动``Tomcat``时,它就会先去加载``web.xml``文件 2.而加载``web.xml``文件时,会碰到``DispacherServlet``需要被加载,所以又会去加载它,当加载``DispacherServlet``时,其实本质上会把``SpringMVC``的组件初始化(执行``init``方法),然后将所有``Controller``的URL资源都映射到一个容器中存储。

hongs468的博客 737

T12 电烙铁简单程序逻辑

通过分析就可以知道,发热丝本身即是发热体,也是热偶的工作端。怎么可能是热电动势呢,确实,但不要忘了T12-OUTPUT端的电压是PWM波,理论上是有单片机PWM电压为0 v时的,而T12-OUTPUT端的电压此时也应为0。在T12烙铁头中,PID控制算法通过监测温度传感器的输出,计算当前温度与设定温度之间的差异,并根据这一差异调节加热功率,以实现烙铁头温度的精确控制。这段代码实现了一个简单的增量式PID控制器,通过计算当前温度与期望温度之间的差异以及历史偏差值,调节输出控制量,实现对温度的精确控制。

hgkhjkljnl的博客 1万+

手写实现SpringMVC

SpringMVC流程图 用户发送请求至前端控制器DispatcherServlet。 DispatcherServlet收到请求调用HandlerMapping处理器映射器。 处理器映射器找到具体的处理器(可以根据xml配置、注解进行查找),生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。 DispatcherServlet调用HandlerAdapter处理器适配器。 HandlerAdapter经过适配调用具体的处理器(Controlle

qq_43843037的博客 689

Unity布娃娃系统 Ragdoll Mecanim Mixer使用

6. 选完之后,左键下面的hip等角色各个部位不松开鼠标,拖拽连接到上面Amature的各个部位,如图,下面所有部位都连接完之后,第二步点击Configure Selected Bones确认你的部位连接选择。要做一个布娃娃和动画混合的项目,这个插件是比较不错的,搜了一圈文章教程也是抄来抄去,抄的没有头没有尾,自己摸索着用了一下,记录使用过程吧。8. 之后就点击步骤7图一中的Create Ragdoll,会发现player结构发生变化,如图。4. 添加完脚本之后会显示你的player结构,如图。

SuShengQuanshiW的博客 1649

详解【计算机类&面试真题】军队文职考试——第7期:C盘格式化需要注意什么?| 两台笔记本连起来后ping不同,可能存在哪些问题?| 模拟信号到数字信号是如何转化的?| 计算机由哪些部件组成?

这是我分享的系列面试知识——军队文职(计算机类)面试真题详解(第7期)。本期分享:两台笔记本连起来后ping不同,你觉得可能存在哪些问题?模拟信号到数字信号是如何转化的?谈一谈计算机由哪些部件组成?如何加强计算机网络安全管理?若通过域名无法访问,而通过IP地址能访问。这是怎么回事?你将如何解决?谈一谈C盘格式化需要注意什么?开放类题目:如果应聘的岗位和你想的差距很远,你怎么办?

追光者♂:记录、分享、总结、提升,现象级专栏《Python从入门到人工智能》作者,无惧黑暗,坚信曙光 1921

手写 Spring MVC

手写 Spring 不多说,简历装 X 必备。不过练好还是需要求一定的思维能力。 一、整体思路 思路要熟练背下来 1)配置阶段 配置 web.xml: XDispatchServlet 设定 init-param: contextConfigLocation = classpath:application.xml 设定 url-pattern: /* 配置 Annotation: @XContr...

肖朋伟 5万+

【数据库系统工程师】5.4Internet基础知识

目录一、思维导图二、知识点1.Internet 概述2.Internet 地址(1)域名(2)IP 地址(3)NAT技术(4)IPv6简介3.Internet 服务(1)域名服务(2)远程登录服务(3)电子邮件服务(4)WWW服务(5)文件传输服务 一、思维导图 二、知识点 1.Internet 概述 2.Internet 地址 (1)域名 ○ 一个完整、通用的层次型主机域名由如下4部分组成: 计算机主机名.本地名.组名.最高层域名 (2)IP 地址 ○ 每个IP地址都由4个小于256的数字组成,数字之

邓邓子的博客 911

Spring的笔记之手写一个简单的mvc框架

这是最近学习的一些整理,通过手写一个mvc的框架来认识和了解Spring的一些工作原理。 首先简单介绍一下Sprin的ioc容器,从本质上来说ioc容器就是一个以beanId为key,class为value的hashMap。Spring则通过配置文件和注解的方式将类放入到hashMap中。 再来,在mvc框架中,url和method的映射本质上也是一个hashMap,它的key是url,value...

weixin_40547924的博客 266

基于STM32L4XX、HAL库的ESP32-S3-WROOM-1-N4 WIFI模块驱动程序设计

/ 检查是否收到完整的一行(以\r\n结尾)// 例如: 解析AT命令响应或MQTT消息等。// UART2初始化已在CubeMX中配置。// USART2初始化函数(由CubeMX生成)// 缓冲区溢出,重置。// 如果需要等待响应。// 处理接收到的数据。// 处理接收到的数据。// 等待ESP32模块启动。// 主循环其他任务。// 启用UART全局中断。// 发送HTTP GET请求。// 发送AT测试命令。// 连接Wi-Fi。// UART中断回调函数。

zhusl6688的博客 286

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

Spring MVC源码解析:基于Servlet手写一个Spring MVC

Spring MVC执行流程 Spirng MVC的执行流程是一个非常重要的知识点,它可以让我们很清楚的了解Spring MVC是如何工作的,后面我们会通过源码的方式整个流程以及涉及到的组件。再开始分析之前,我打算基于Servlet手写一个Spirng MVC,这样你就能明白大概的执行流程,不至于在看源码的时候太晕。 定义注解 @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface Controlle.

小识的博客 1294

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

05. 手写Spring核心框架

目录 05 手写Spring核心框架 Pt1 手写IoC/DI Pt1.1 流程设计 Pt1.2 基础配置 application.properties pom.xml web.xml Pt1.3 注解定义 @MyController @MyService @MyAutowired @MyRequestMapping @MyRequestParam Pt1.4 核心代码 DispatcherServlet ApplicationContext BeanDefinition

Java是世界上最好的语言 5537

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

从0到1手写Spring MVC教程

本教程从0到1实现简易SpringMVC框架,核心包括:1)自定义@GetMapping注解;2)DispatcherServlet处理请求分发;3)Controller接收参数并返回ModelAndView;4)ViewEngine模板引擎渲染视图。通过反射扫描Controller类,建立URL到方法的映射关系,使用Pebble模板引擎实现页面渲染。教程提供了完整代码实现,包括核心组件DispatcherServlet、GetDispatcher、ModelAndView等

2401_87929230的博客 964

springboot - 手写spring mvc

springboot - 手写spring mvc

lin000_0的博客 769

Spring Boot Spring MVC

Spring MVC 是一个基于模型-视图-控制器(MVC)模式的 Web 框架,提供了一整套处理 HTTP 请求的工具,包括控制器(Controller)、视图解析(View Resolver)和模型绑定(Model Binding)。

Flying_Fish_roe的博客 2001

一个简单的spring mvc实例

 这篇文章将教你快速地上手使用 Spring 框架. 如果你手上有一本《Spring in Action》, 那么你最好从第三部分"Spring 在 Web 层的应用--建立 Web 层"开始看, 否则那将是一场恶梦! 首先, 我需要在你心里建立起 Spring MVC 的基本概念. 基于 Spring 的 Web 应用程序接收到 http://localhost:8080/hello.d

yuqiangyuqiang的专栏 1万+

手写一个简单版本的spring MVC

pom.xml <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target&gt

小城我家 192

Maven构建一个最简单的Spring Boot + Spring MVC项目

使用Maven构建一个最简单的Spring MVC + Spring Boot项目,完全基于java config 一、新建一个maven项目,模板使用quickstart POM.xml配置: <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSch

luenxin的博客 9964

14.手写Spring MVC

本文介绍了手写Spring MVC框架的基本流程。首先搭建Maven项目结构并引入Servlet依赖,配置Tomcat服务器和web支持。然后创建核心接口和类,包括DispatcherServlet、HandlerMapping、HandlerAdapter等。重点实现了@Controller、@RequestMapping注解及HandlerMethod类,用于标记控制器和处理请求方法。通过构建这些基础组件,为后续实现完整的MVC框架奠定了基础。

u011488477的博客 603

Spring 4.0手写 之Spring MVC

摘要:本课程旨在通过手写简化版SpringMVC框架来深入理解其核心原理。主要内容包括:1)实现MVC顶层设计,包含调度中心GPDispatcherServlet、请求映射GPHandlerMapping和适配器GPHandlerAdapter;2)开发业务层和控制器逻辑;3)定制模板引擎实现视图解析;4)演示完整请求生命周期。通过模拟SpringMVC的请求分发、业务处理、视图返回全流程,帮助学习者掌握DispatcherServlet调度机制、HandlerMapping映射原理以及模板方法等设计模式在

weixin_47759174的博客 869
上一篇: 【学习笔记】手写一个简单的 Spring IOC
下一篇: 【学习笔记】【SpringCloud】MybatisPlus 基础使用
LearnTech_123
博客等级 码龄3年 445粉丝 31原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值