实现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 {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {super.doGet(req, resp);}@Overrideprotected 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 {@Overridepublic void init(ServletConfig config) throws ServletException {//初始化容器SunWebApplicationContext sunWebApplicationContext = new SunWebApplicationContext();sunWebApplicationContext.init();}@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("doGet");}@Overrideprotected 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文件的名字去掉.classString 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; //映射的urlprivate 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;}@Overridepublic 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;@Overridepublic void init(ServletConfig config) throws ServletException {//初始化容器sunWebApplicationContext = new SunWebApplicationContext();sunWebApplicationContext.init();//初始化映射列表initHandlerMapping();System.out.println("ss");}@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {doPost(req, resp);}@Overrideprotected 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/monsterString requestURI = request.getRequestURI();String contextPath = request.getServletContext().getContextPath();//遍历映射对象列表,查看列表中是否有这个urifor (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 {//当映射对象是空的时候,返回404try {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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【stomp 实战】Spring websocket使用详解和基本原理

spring框架对websocket有很好的支持&#xff0c;stomp协议作为websocket的子协议&#xff0c;Spring也做了很多封装&#xff0c;让我们在开发中易于使用。 学习使用Spring的Websocket模块&#xff0c;当然最好的办法就是看官网说明了。本篇文章对官网做一些简述和个人的理解。 …

采集 Kubernetes 容器日志最佳实践

前言 指标、日志、链路是可观测的三大支柱&#xff0c;日志主要用于记录代码执行的痕迹&#xff0c;方便定位和排查问题。当前主流的应用都是以容器的方式运行在 Kubernetes 集群&#xff0c;由于容器的动态性&#xff0c;容器可能会频繁地创建和销毁。日志的采集和持久化变得…

用例整体执行及pytest.ini文件

在我们写代码的过程中&#xff0c;一般都是右键或者命令行去执行一个用例 但是当我们写完后&#xff0c;需要整体执行一遍。那应该怎么搞呢&#xff1f; 我们可以在根目录下新建一个main.py或者run.py之类的文件&#xff0c;文件内容如下&#xff1a; if __name__ "__ma…

JAVA实现easyExcel批量导入

注解类型描述ExcelProperty导入指定当前字段对应excel中的那一列。可以根据名字或者Index去匹配。当然也可以不写&#xff0c;默认第一个字段就是index0&#xff0c;以此类推。千万注意&#xff0c;要么全部不写&#xff0c;要么全部用index&#xff0c;要么全部用名字去匹配。…

个人电脑本地部署LLM

普通电脑配置即可本地运行大模型&#xff0c;本地部署LLM最简单的方法 OLLAMA Ollama是一个开源框架&#xff0c;专门设计用于在本地运行大型语言模型&#xff08;LLM&#xff09;。它的主要功能是在Docker容器中部署和管理LLM&#xff0c;使得在本地运行大模型的过程变得非常…

python之List列表

1. 高级数据类型 Python中的数据类型可以分为&#xff1a;数字型&#xff08;基本数据类型&#xff09;和非数字型&#xff08;高级数据类型&#xff09; 数字型包含&#xff1a;整型int、浮点型float、布尔型bool、复数型complex 非数字型包含&#xff1a;字符串str、列表l…

CPPTest实例分析(C++ Test)

1 概述 CppTest是一个可移植、功能强大但简单的单元测试框架&#xff0c;用于处理C中的自动化测试。重点在于可用性和可扩展性。支持多种输出格式&#xff0c;并且可以轻松添加新的输出格式。 CppTest下载地址&#xff1a;下载地址1  下载地址2 下面结合实例分析下CppTest如…

Vue3+ts(day03:ref和reactive)

学习源码可以看我的个人前端学习笔记 (github.com):qdxzw/frontlearningNotes 觉得有帮助的同学&#xff0c;可以点心心支持一下哈&#xff08;笔记是根据b站上学习的尚硅谷的前端视频【张天禹老师】&#xff0c;记录一下学习笔记&#xff0c;用于自己复盘&#xff0c;有需要学…

ARCGIS PRO3 三维模型OSGB转SLPK场景数据集

1.前言 因项目工作&#xff0c;需要将三维模型发布到arcgisserver上&#xff0c;但arcgisserver只支持slpk格式的模型&#xff0c;于是我开启了漫长的三维模型格式转换之旅&#xff0c;在这里记录下本人踩过的坑。 2.三维模型数据情况 2.1 模型大小&#xff1a;在20GB以上&a…

tcp inflight 守恒算法的自动收敛

inflight 守恒算法看起来只描述理想情况&#xff0c;现实很难满足&#xff0c;是这样吗&#xff1f; 从 reno 到 bbr&#xff0c;无论哪个算法都在描述理想情况&#xff0c;以 reno 和 bbr 两个极端为例&#xff0c;它们分别描述两种理想管道&#xff0c;reno 将 buffer 从恰好…

goroutinue和channel

goroutinue和channel 需求传统方式实现goroutinue进程和线程说明并发和并行go协程和go主线程MPG设置Go运行的cpu数 channel(管道)-看个需求使用互斥锁、写锁channel 实现 使用select可以解决从管道取数据的阻塞问题&#xff08;无需手动关闭channel了&#xff09;goroutinue中使…

61、回溯-分割回文串

思路&#xff1a; 还是全排列的思路&#xff0c;列出每一种组合&#xff0c;然后验证是否是回文&#xff0c;如果是子串放入path中&#xff0c;在验证其他元素是否也是回文。代码如下&#xff1a; class Solution {// 主方法&#xff0c;用于接收一个字符串s并返回所有可能的…

智能变频三模正弦波控制器

智能变频三模正弦波控制器 前言一、图片介绍总结 前言 不敢动&#xff0c;完全不敢动。多做笔记&#xff0c;完全了解之后再说吧 一、图片介绍 轮毂电机 主角登场 淘宝关于这款控制器的介绍 当然不同的型号功能不同 学习线插上就会转,可以使用继电器控制通断。 电门…

mac资源库的东西可以删除吗?提升Mac运行速度秘籍 Mac实用软件

很多小伙伴在使用mac电脑处理工作的时候&#xff0c;就会很疑惑&#xff0c;电脑的运行速度怎么越来越慢&#xff0c;就想着通过删除mac资源库的东西&#xff0c;那么mac资源库的东西可以删除吗&#xff1f;删除了会不会造成电脑故障呢&#xff1f; 首先&#xff0c;mac资源库…

解决ax = Axes3D(fig2)pycharm画3d图空白不显示问题

明明代码运行正确&#xff0c;却总是显示不出来 绘制出来的也是空白 改一下代码就好了 ax Axes3D(fig2) #原来代码 ax fig2.add_axes(Axes3D(fig2)) #改后代码 修改过后就可以显示了

深入了解MySQL:从基础到特性,全面解读关系数据库管理系统的历史与应用

文章目录 1. MySQL简介1.1 概述1.2 架构与兼容性1.3 开源与社区支持 2. MySQL的历史2.1 创始与初衷2.2 发展历程2.3 在Oracle的持续发展2.4 开源与商业结合 3. MySQL的核心特性4. MySQL在实际应用中的作用4.1 网站建设与内容管理4.2 商业智能与客户关系管理4.3 企业级应用与云集…

线性代数 --- 计算斐波那契数列第n项的快速算法(矩阵的n次幂)

计算斐波那契数列第n项的快速算法(矩阵的n次幂) The n-th term of Fibonacci Numbers&#xff1a; 斐波那契数列的是一个古老而又经典的数学数列&#xff0c;距今已经有800多年了。关于斐波那契数列的计算方法不难&#xff0c;只是当我们希望快速求出其数列中的第100&#xff0…

mysql8.0免安装版windows

1.下载 MySQL下载链接 2.解压与新建my.ini文件 解压的路径最好不要有中文路径在\mysql-8.0.36-winx64文件夹下新建my.ini文件&#xff0c;不建data文件夹(会自动生成) [mysqld] # 设置3306端口 port3306 # 设置mysql的安装目录(尽量用双斜杠\\,单斜杠\可能会报错) basedirD:\…

uniapp获取当前位置及检测授权状态

uniapp获取当前位置及检测授权定位权限 文章目录 uniapp获取当前位置及检测授权定位权限效果图创建js文件permission.jslocation.js 使用 效果图 Android设备 点击 “设置”&#xff0c;跳转应用信息&#xff0c;打开“权限即可”&#xff1b; 创建js文件 permission.js 新建…

3d合并的模型为什么没有模型---模大狮模型网

在3D建模中&#xff0c;合并模型是常见的操作&#xff0c;它可以将多个模型合并成一个整体。然而&#xff0c;有时候在合并后却发现部分模型消失了&#xff0c;这可能会让人感到困惑和失望。本文将探讨为什么合并的3D模型中会出现没有模型的情况&#xff0c;并提供一些解决方法…