实现SpringMVC底层机制(一)

文章目录

    • 1.环境配置
        • 1.创建maven项目
        • 2.创建文件目录
        • 3.导入jar包
    • 2.开发核心控制器
        • 文件目录
        • 1.流程图
        • 2.编写核心控制器SunDispatcherServlet.java
        • 3.类路径下编写spring配置文件sunspringmvc.xml
        • 4.配置中央控制器web.xml
        • 5.配置tomcat,完成测试
          • 1.配置发布方式
          • 2.配置热加载
          • 3.修改SunDispatcherServlet.java
          • 4.完成测试
    • 3.完成客户端/浏览器可以请求控制层
        • 文件目录
        • 1.思路分析
        • 2.编写MonsterController.java
        • 3.自定义注解
          • 1.Controller.java
          • 2.RequestMapping.java
        • 4.自定义容器(1),在tomcat启动时读取配置文件,获取要扫描的包的工作路径
          • 1.SunWebApplicationContext.java
          • 2.修改SunDispatcherServlet.java
          • 3.单元测试,启动tomcat
        • 5.自定义容器(2),在tomcat启动的时候完成对指定包的扫描
          • 1.修改SunWebApplicationContext.java
          • 2.debug测试
        • 6.将自定义容器(3),符合要求的类反射创建对象,放到单例池
          • 1.修改SunWebApplicationContext.java增加方法,添加属性
          • 2.debug查看单例池
        • 7.完成url和控制器方法映射
          • 1.创建映射bean,SunHandler.java
          • 2.修改中央控制器SunWebApplicationContext.java添加方法和属性
          • 3.debug查看映射对象列表
        • 8.完成请求分发到目标方法
          • 1.修改SunDispatcherServlet.java,添加两个方法并在dopost中请求分发
          • 2.单元测试
    • 4.当前阶段完成的功能
        • 1.初始化阶段
        • 2.完成请求分发

1.环境配置

1.创建maven项目

image-20240227084815460

2.创建文件目录

image-20240227085226577

3.导入jar包
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>org.example</groupId>
  <artifactId>sun-springmvc</artifactId>
  <packaging>war</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>sun-springmvc Maven Webapp</name>
  <url>http://maven.apache.org</url>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
    <!--servlet原生api-->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
      <!--在项目打包时不会带上这个jar-->
      <scope>provided</scope>
    </dependency>
    <!--解析xml-->
    <dependency>
      <groupId>dom4j</groupId>
      <artifactId>dom4j</artifactId>
      <version>1.6.1</version>
    </dependency>
    <!--常用工具类-->
    <dependency>
      <groupId>org.apache.commons</groupId>
      <artifactId>commons-lang3</artifactId>
      <version>3.5</version>
    </dependency>
  </dependencies>
  <build>
    <finalName>sun-springmvc</finalName>
  </build>
</project>

2.开发核心控制器

文件目录

image-20240227095105084

1.流程图

image-20240227093109208

2.编写核心控制器SunDispatcherServlet.java
package com.Sun.sunspringmvc.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 充当中央控制器
 *
 * @author 孙显圣
 * @version 1.0
 */
public class SunDispatcherServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doGet(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }
}

3.类路径下编写spring配置文件sunspringmvc.xml
4.配置中央控制器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>SunDispatcherServlet</servlet-name>
    <servlet-class>com.Sun.sunspringmvc.servlet.SunDispatcherServlet</servlet-class>
    <!--init—param设置spring配置文件的位置-->
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:sunspringmvc.xml</param-value>
    </init-param>
    <!--服务器启动时实例化servlet,将其放到容器中,并且调用init方法-->
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>SunDispatcherServlet</servlet-name>
    <!--拦截所有请求-->
    <url-pattern>/</url-pattern>
  </servlet-mapping>


</web-app>

5.配置tomcat,完成测试
1.配置发布方式

image-20240227092658306

2.配置热加载

image-20240227092725037

3.修改SunDispatcherServlet.java

image-20240227092846449

4.完成测试

image-20240227092956993

image-20240227093009005

3.完成客户端/浏览器可以请求控制层

文件目录

image-20240227165505347

1.思路分析

image-20240227143426184

2.编写MonsterController.java
package com.Sun.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * @author 孙显圣
 * @version 1.0
 */
public class MonsterController {
    public void listMonster(HttpServletRequest request, HttpServletResponse response) {
        //设置mine类型
        response.setContentType("text/html;charset=utf-8");
        try {
            PrintWriter writer = response.getWriter();
            writer.write("<h1>妖怪列表信息</h1>");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

3.自定义注解
1.Controller.java
package com.Sun.sunspringmvc.annotation;

import java.lang.annotation.*;

/**
 * 用于标识一个Controller
 *
 * @author 孙显圣
 * @version 1.0
 */
@Target(ElementType.TYPE) //作用于类型
@Retention(RetentionPolicy.RUNTIME) //作用范围
@Documented
public @interface Controller {
}

2.RequestMapping.java
package com.Sun.sunspringmvc.annotation;

import java.lang.annotation.*;

/**
 * 用于指定映射路径
 *
 * @author 孙显圣
 * @version 1.0
 */
@Target(ElementType.METHOD) //作用于方法
@Retention(RetentionPolicy.RUNTIME) //作用范围
@Documented
public @interface RequestMapping {
}

4.自定义容器(1),在tomcat启动时读取配置文件,获取要扫描的包的工作路径
1.SunWebApplicationContext.java
package com.Sun.sunspringmvc.context;

import com.Sun.sunspringmvc.xml.XmlParser;

import java.net.URL;
import java.util.ArrayList;
import java.util.List;

/**
 * @author 孙显圣
 * @version 1.0
 */
public class SunWebApplicationContext {
    //存放所有要扫描的包下的class文件的全路径
    private List<String> classFullPathList = new ArrayList<String>();

    //初始化容器
    public void init() {
        //读取spring配置文件,获取要扫描的包的信息
        String basePage = XmlParser.getBasePage("sunspringmvc.xml");
        //完成对指定包的扫描
        scanPage(basePage);
    }

    //创建方法,完成对指定包的扫描,获取所有class文件的全路径
    public void scanPage(String packFullName) {
        //将包的全类名中的点替换为斜杠
        String packPath = packFullName.replaceAll("\\.", "/");

        //通过类加载器来获取这个包的工作路径,就是获取工作路径下的类路径下的文件路径
        URL resource = SunWebApplicationContext.class.getClassLoader().getResource(packPath);
        System.out.println(resource);
    }
}

2.修改SunDispatcherServlet.java
package com.Sun.sunspringmvc.servlet;

import com.Sun.sunspringmvc.context.SunWebApplicationContext;

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;

/**
 * 充当中央控制器
 *
 * @author 孙显圣
 * @version 1.0
 */
public class SunDispatcherServlet extends HttpServlet {
    @Override
    public void init(ServletConfig config) throws ServletException {
        //初始化容器
        SunWebApplicationContext sunWebApplicationContext = new SunWebApplicationContext();
        sunWebApplicationContext.init();

    }

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

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

3.单元测试,启动tomcat

image-20240227133426603

5.自定义容器(2),在tomcat启动的时候完成对指定包的扫描
1.修改SunWebApplicationContext.java
package com.Sun.sunspringmvc.context;

import com.Sun.sunspringmvc.xml.XmlParser;

import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

/**
 * @author 孙显圣
 * @version 1.0
 */
public class SunWebApplicationContext {
    //存放所有要扫描的包下的class文件的全路径
    private List<String> classFullPathList = new ArrayList<String>();

    //初始化容器
    public void init() {
        //读取spring配置文件,获取要扫描的包的信息
        String basePage = XmlParser.getBasePage("sunspringmvc.xml");
        //初始化容器
        //根据逗号进行分割,得到多个要扫描的包的全路径,遍历将里面的class文件全路径放到列表中
        String[] split = basePage.split(",");
        for (String packPath : split) {
            scanPage(packPath);
        }
    }

    //创建方法,完成对指定包的扫描,获取所有class文件的全路径
    public void scanPage(String packFullName) {
        //将包的全类名中的点替换为斜杠
        String packPath = packFullName.replaceAll("\\.", "/");

        //通过类加载器来获取这个包的工作路径,就是获取工作路径下的类路径下的文件路径
        URL url = SunWebApplicationContext.class.getClassLoader().getResource(packPath);
        //得到路径
        String file = url.getFile();
        //根据这个文件夹来创建一个file对象,从而遍历里面所有的class文件得到所有class文件的全路径
        File packDirectory = new File(file);
        if (packDirectory.isDirectory()) {
            //如果是文件夹则列出里面的所有文件对象
            File[] files = packDirectory.listFiles();
            //遍历这些文件对象,实际上就那个包下的所有class文件对象
            for (File classFile : files) {
                //如果这里的文件对象还是文件夹,则进行递归扫描
                if (classFile.isDirectory()) {
                    scanPage(packFullName + "." + classFile.getName());
                } else {
                    //如果这里的文件对象指的都是文件,则将其放到classFullPathList中
                    //得到当前文件的全类名 = 包的全路径 + class文件的名字去掉.class
                    String classFullPath = packFullName + "." + classFile.getName().replaceAll(".class", "");
                    //放到列表中
                    classFullPathList.add(classFullPath);
                }
            }
        }
    }

}

2.debug测试

image-20240227143135578

6.将自定义容器(3),符合要求的类反射创建对象,放到单例池
1.修改SunWebApplicationContext.java增加方法,添加属性

image-20240227145800640

    //编写方法,将符合要求的类反射创建对象,并封装到单例池中
    public void executeInstance(){
        //遍历所有全类名
        for (String classPath : classFullPathList) {
            try {
                //反射
                Class<?> aClass = Class.forName(classPath);
                //判断是否有Controller注解
                if (aClass.isAnnotationPresent(Controller.class)) {
                    //有注解,当他是单例的,反射创建bean对象,放到单例池中,默认首字母小写
                    //获取类名首字母小写
                    String name = aClass.getSimpleName().substring(0, 1).toLowerCase() + aClass.getSimpleName().substring(1);
                    //放到单例池中
                    singleObjects.put(name, aClass.newInstance());
                }
            } catch (ClassNotFoundException e) {
                throw new RuntimeException(e);
            } catch (InstantiationException e) {
                throw new RuntimeException(e);
            } catch (IllegalAccessException e) {
                throw new RuntimeException(e);
            }
        }
    }

2.debug查看单例池

image-20240227145600884

7.完成url和控制器方法映射
1.创建映射bean,SunHandler.java
package com.Sun.sunspringmvc.handler;

import java.lang.reflect.Method;

/**
 * 用于存放有注解的类的映射信息
 *
 * @author 孙显圣
 * @version 1.0
 */
public class SunHandler {
    private String url; //映射的url
    private Object controller; //controller对象
    private Method method; //方法对象,用于反射调用方法

    public SunHandler(String url, Object controller, Method method) {
        this.url = url;
        this.controller = controller;
        this.method = method;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public Object getController() {
        return controller;
    }

    public void setController(Object controller) {
        this.controller = controller;
    }

    public Method getMethod() {
        return method;
    }

    public void setMethod(Method method) {
        this.method = method;
    }

    @Override
    public String toString() {
        return "SunHandler{" +
                "url='" + url + '\'' +
                ", controller=" + controller +
                ", method=" + method +
                '}';
    }
}

2.修改中央控制器SunWebApplicationContext.java添加方法和属性

image-20240227155457879

    //初始化映射对象列表,获取映射对象并且将其放到映射列表中
    private void initHandlerMapping() {
        //判断单例池是否为空
        if (sunWebApplicationContext.singleObjects.isEmpty()) {
            return;
        }
        //取出单例池里的所有对象
        for (Map.Entry<String, Object> entry : sunWebApplicationContext.singleObjects.entrySet()) {
            //反射
            Class<?> aClass = entry.getValue().getClass();
            //判断是否有colltroller注解
            if (aClass.isAnnotationPresent(Controller.class)) {
                //反射获取所有方法对象
                Method[] declaredMethods = aClass.getDeclaredMethods();
                //判断方法里是否有requestmapping注解
                for (Method declaredMethod : declaredMethods) {
                    if (declaredMethod.isAnnotationPresent(RequestMapping.class)) {
                        //获取这个方法的注解信息
                        String url = declaredMethod.getAnnotation(RequestMapping.class).value();
                        //将信息封装到映射bean对象中
                        SunHandler sunHandler = new SunHandler(url, entry.getValue(), declaredMethod);
                        //添加到列表中
                        handlers.add(sunHandler);
                    }
                }
            }
        }
    }
3.debug查看映射对象列表

8.完成请求分发到目标方法
1.修改SunDispatcherServlet.java,添加两个方法并在dopost中请求分发
package com.Sun.sunspringmvc.servlet;

import com.Sun.sunspringmvc.annotation.Controller;
import com.Sun.sunspringmvc.annotation.RequestMapping;
import com.Sun.sunspringmvc.context.SunWebApplicationContext;
import com.Sun.sunspringmvc.handler.SunHandler;

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.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 充当中央控制器
 *
 * @author 孙显圣
 * @version 1.0
 */
public class SunDispatcherServlet extends HttpServlet {
    //存放所有的映射关系
    private List<SunHandler> handlers = new ArrayList<SunHandler>();
    private SunWebApplicationContext sunWebApplicationContext = null;

    @Override
    public void init(ServletConfig config) throws ServletException {
        //初始化容器
        sunWebApplicationContext = new SunWebApplicationContext();
        sunWebApplicationContext.init();
        //初始化映射列表
        initHandlerMapping();
        System.out.println("ss");
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //请求分发
        executeDispatch(req, resp);
    }

    //初始化映射对象列表,获取映射对象并且将其放到映射列表中
    private void initHandlerMapping() {
        //判断单例池是否为空
        if (sunWebApplicationContext.singleObjects.isEmpty()) {
            return;
        }
        //取出单例池里的所有对象
        for (Map.Entry<String, Object> entry : sunWebApplicationContext.singleObjects.entrySet()) {
            //反射
            Class<?> aClass = entry.getValue().getClass();
            //判断是否有colltroller注解
            if (aClass.isAnnotationPresent(Controller.class)) {
                //反射获取所有方法对象
                Method[] declaredMethods = aClass.getDeclaredMethods();
                //判断方法里是否有requestmapping注解
                for (Method declaredMethod : declaredMethods) {
                    if (declaredMethod.isAnnotationPresent(RequestMapping.class)) {
                        //获取这个方法的注解信息
                        String url = declaredMethod.getAnnotation(RequestMapping.class).value();
                        //将信息封装到映射bean对象中
                        SunHandler sunHandler = new SunHandler(url, entry.getValue(), declaredMethod);
                        //添加到列表中
                        handlers.add(sunHandler);
                    }
                }
            }
        }
    }

    //根据请求对象得到映射对象
    private SunHandler getSunHandler(HttpServletRequest request) {
        //获取uri: /sun-springmvc/list/monster
        String requestURI = request.getRequestURI();
        String contextPath = request.getServletContext().getContextPath();
        //遍历映射对象列表,查看列表中是否有这个uri
        for (SunHandler handler : handlers) {
            //这里拼接一个上下文路径
            if ((contextPath + "/" + handler.getUrl()).equals(requestURI)) {
                //返回这个映射对象
                return handler;
            }
        }
        return null;
    }

    //请求分发
    private void executeDispatch(HttpServletRequest request, HttpServletResponse response) {
        //获取映射对象
        SunHandler sunHandler = getSunHandler(request);
        //映射对象不等于空则反射调用controller的方法
        if (sunHandler != null) {
            try {
                sunHandler.getMethod().invoke(sunHandler.getController(), request, response);
            } catch (IllegalAccessException e) {
                throw new RuntimeException(e);
            } catch (InvocationTargetException e) {
                throw new RuntimeException(e);
            }
        } else {
            //当映射对象是空的时候,返回404
            try {
                response.getWriter().write("<h1>404 not found!</h1>");
            } catch (IOException e) {
                throw new RuntimeException(e);
            }

        }
    }
}

2.单元测试

image-20240227164234686

image-20240227164244515

image-20240227164254432

4.当前阶段完成的功能

1.初始化阶段
  • tomcat服务器启动,自动装载中央控制器(servlet),调用init方法
  • 初始化spring容器
    • 创建spring容器实例,调用init方法
    • 读取spring配置文件,得到要扫描的包的工作路径
    • 扫描指定的包,获取所有class文件的全路径
    • 扫描所有class文件,将包含Controller注解的类反射创建对象放到单例池中(这里假设都是单例的)
  • 初始化映射对象列表
    • 扫描所有单例池中的对象
    • 反射获取这个对象对应类的所有方法,如果方法包含RequestMapping注解,则将这个对象,url,Method对象封装到映射对象中,并且添加到映射对象列表
2.完成请求分发
  • 根据请求对象得到映射对象
    • 获取请求的uri
    • 遍历对象映射列表查看是否有匹配的映射对象,如果有则返回映射对象
  • 请求分发
    • 首先根据请求对象得到映射对象
    • 如果得到了就反射调用方法
    • 没有得到则返回404

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/577189.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

创建Spring Boot项目

选择Maven Archetype,之后再Archetype选择webapp 两个都打勾 这是当前的打勾 这个是以后都默认勾上 打开对应的路径&#xff0c;用vscode打开settings.xml 加入国内源 阿里云 若没有此文件可上网查找 若jar包出现问题&#xff0c;可在repostitory文件内全删除 之后在Maven刷…

巴特沃斯滤波原理及代码实现(matlab详细过程版)

目录 一、算法原理1、原理概述2、参考文献 二、代码实现三、结果展示 本文由CSDN点云侠原创&#xff0c;原文链接。如果你不是在点云侠的博客中看到该文章&#xff0c;那么此处便是不要脸的爬虫与GPT。 一、算法原理 1、原理概述 巴特沃斯滤波器&#xff08;Butterworth filt…

主成分分析(PCA)在 Java 中的简单应用

在数据科学的众多工具中&#xff0c;主成分分析&#xff08;PCA&#xff09;是一种非常重要的统计技术&#xff0c;用于数据降维和模式识别。它通过提取数据中的关键特征来简化数据结构&#xff0c;从而帮助我们更好地理解数据集的主要变化因素。本文将介绍如何在 Java 编程环境…

CARLA (I)--Ubuntu20.04 服务器安装 CARLA_0.9.13服务端和客户端详细步骤

目录 0. 说明0.1 应用场景&#xff1a;0.2 本文动机&#xff1a; 1. 准备工作2. 安装 CARLA 服务端软件【远程服务器】3. 安装 CARLA 客户端【远程服务器】3.1 .egg 文件安装&#xff1a;3.2 .whl 文件安装&#xff1a;3.3 从Pypi下载Python package 4. 运行服务端程序5. 运行客…

arcgis js 4.x加载SceneLayer并实现基于属性查询定位及高亮

一、代码 <!DOCTYPE html> <html> <head><meta charset"utf-8" /><meta name"viewport" content"widthdevice-width, initial-scale1,maximum-scale1,user-scalableno"><title></title><link rel…

北京车展创新纷呈,移远通信网联赋能

时隔四年&#xff0c;备受瞩目的2024&#xff08;第十八届&#xff09;北京国际汽车展览会于4月25日盛大开幕。在这场汽车行业盛会上&#xff0c;各大主流车企竞相炫技&#xff0c;众多全球首发车、概念车、新能源车在这里汇聚&#xff0c;深刻揭示了汽车产业的最新成果和发展潮…

神经网络的激活函数

目录 神经网络 激活函数 sigmoid 激活函数 tanh 激活函数 backward方法 relu 激活函数 softmax 激活函数 神经网络 人工神经网络&#xff08; Artificial Neural Network&#xff0c; 简写为ANN&#xff09;也简称为神经网络&#xff08;NN&#xff09;&#xff0c…

杰发科技AC7840——CAN通信简介(7)_波形分析

参考&#xff1a; CAN总线协议_stm32_mustfeng-GitCode 开源社区 0. 简介 隐形和显性波形 整帧数据表示 1. 字节描述 CAN数据帧标准格式域段域段名位宽&#xff1a;bit描述帧起始SOF(Start Of Frame)1数据帧起始标志&#xff0c;固定为1bit显性(b0)仲裁段dentify(ID)11本数…

c++图论基础(2)

目录 图的存储方式&#xff1a; 邻接矩阵&#xff1a; 代码实现&#xff1a; 邻接表&#xff1a; 代码实现&#xff1a; 邻接矩阵邻接表对比&#xff1a; 带权图&#xff1a; 邻接矩阵存储&#xff1a; 邻接表存储(代码实现)&#xff1a; 图的存储方式&#xff1a; 邻…

Unreal Engine添加UGameInstanceSubsystem子类

点击C类文件夹&#xff0c;在右边的区域点击鼠标右键&#xff0c;在弹出的菜单中选择“新建C类”在弹出的菜单中选中“显示所有类”&#xff0c;选择GameInstanceSubsystem作为父类, 点击“下一步”按钮输入子类名称“UVRVIUOnlineGameSubsystem”&#xff0c;选择插件作为新类…

Qt 创建控件的两种方式

目录 Qt 创建控件的两种方式 通过ui界面创建控件 通过代码方式创建控件 Qt 创建控件的两种方式 通过ui界面创建控件 这里当然我们是需要先有一个项目的&#xff0c;按照我们之前创建项目的步骤&#xff0c;我们可以先创建一个 Widget 的项目&#xff0c;但是 MainWindow 也…

EasyRecovery数据恢复软件2025激活码及下载使用步骤教程

EasyRecovery数据恢复软件是一款功能强大且用户友好的数据恢复工具&#xff0c;专为帮助用户找回因各种原因丢失的数据而设计。该软件由全球知名的数据恢复技术公司开发&#xff0c;经过多年的技术积累和更新迭代&#xff0c;已经成为行业内备受推崇的数据恢复解决方案。 EasyR…

Spring MVC系列之九大核心组件

概述 Spring MVC是面试必问知识点其一&#xff0c;Spring MVC知识体系庞杂&#xff0c;有以下九大核心组件&#xff1a; HandlerMappingHandlerAdapterHandlerExceptionResolverViewResolverRequestToViewNameTranslatorLocaleResolverThemeResolverMultipartResolverFlashMa…

Andorid复习

组件 TextView 阴影 android:shadowColor"color/red" 阴影颜色android:shadowRadius"3.0" 阴影模糊度&#xff08;大小&#xff09;android:shadowDx"10.0" 横向偏移android:shadowDy"10.0" 跑马灯 这里用自定义控件 public cla…

【Java】HOT100 回溯

目录 理论基础 一、组合问题 LeetCode77&#xff1a;组合 LeetCode17&#xff1a;电话号码的字母组合 LeetCode39&#xff1a;组合总和 LeetCode216&#xff1a;组合总和ii LeetCode216&#xff1a;组合总和iii 二、分割问题 LeetCode131&#xff1a;分割回文串 Leet…

MFC实现ini配置文件的读取

MFC实现 ini 配置文件的读取1 实现的功能&#xff1a;点击导入配置文件按钮可以在旁边编辑框中显示配置文件的路径&#xff0c;以及在下面的编辑框中显示配置文件的内容。 1. 显示配置文件内容的编辑框设置 对于显示配置文件内容的 Edit Contorl 编辑框的属性设置如下&#x…

vue3中所有页面需要手动刷新一下才能显示,控制台没有报错

1.问题 登录进来是进入首页&#xff0c;然后切换任何页面都是空白&#xff0c;但是控制台没有报错。在其他页面刷新后却能显示&#xff0c;然而切换到首页刷新后再切换到其他页面又是空白。 2.解决问题 原因&#xff1a;在于首页给了两个根标签&#xff0c;我把其中一个根标签…

视频输入c++ 调用 libtorch推理

1、支持GPU情况 libtorch 支持GPU情况比较奇怪&#xff0c;目前2.3 版本需要在链接器里面加上以下命令&#xff0c;否则不会支持gpu -INCLUDE:?ignore_this_library_placeholderYAHXZ 2 探测是否支持 加一个函数看你是否支持torch&#xff0c;不然不清楚&#xff0c;看到…

axios——503响应超时重复多次请求——技能提升

今天在写后台管理系统时&#xff0c;遇到一个问题&#xff0c;就是每天早上一启动项目&#xff0c;接口会提示503超时&#xff0c;因此项目运行必须重新刷新请求成功后才可以正常使用。 后端同事说请求超时了&#xff0c;需要前端处理一下&#xff0c;如果是503的状态码&#…

封装 H.264 视频为 FLV 格式然后推流

封装 H.264 视频为 FLV 格式并通过 RTMP 推流 flyfish 协议 RTMP (Real-Time Messaging Protocol) RTSP (Real Time Streaming Protocol) SRT (Secure Reliable Transport) WebRTC RTMP&#xff08;Real Time Messaging Protocol&#xff09;是一种用于实时音视频流传输的协…