仿写SpringMVC

1.创建简单的注解

1.1 Controller

package com.heaboy.annotation;import java.lang.annotation.*;@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @ interface Controller {
}

1.2 RequestMapping

package com.heaboy.annotation;import java.lang.annotation.*;@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE,ElementType.METHOD})
public @interface RequestMapping {String value() default "";
}

2.创建controller类

package com.heaboy.controller;import com.heaboy.annotation.Controller;
import com.heaboy.annotation.RequestMapping;@Controller
@RequestMapping("test")
public class TestController {@RequestMappingpublic String index(){System.out.println("test->index");return "";}@RequestMapping("index1")public String index1(){System.out.println("test->index1");return "";}
}
package com.heaboy;import com.heaboy.annotation.Controller;
import com.heaboy.annotation.RequestMapping;@Controller
@RequestMapping
public class IndexController {@RequestMappingpublic void index(){System.out.println("index -> index");}
}

3.SpingMVC实现类

package com.heaboy.mvc;import com.heaboy.Main;
import com.heaboy.annotation.Controller;
import com.heaboy.annotation.RequestMapping;import java.io.File;
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.nio.channels.ClosedSelectorException;
import java.sql.SQLOutput;
import java.util.*;
import java.util.regex.Matcher;public class HeaboyMvc {private static HashMap<String, Map<String,Method>> map=new HashMap<>();private static HashMap<String,Object> objMap=new HashMap<>();public static void scanner(String path,String packageName)  {//扫描main所在包中的类以及子包中的类的绝对路径List<String> paths=traverseFolder2(path);for (String p : paths) {p=p.substring(path.length()-1);//遍历每一个类文件的绝对路径,并且处理只剩下对main的相对路径try {String className=packageName+"."+p.replaceAll(Matcher.quoteReplacement(File.separator),".");//包名加相对路径,把相对路径的/换成.String replace=className.replace(".class","");//去掉.class后缀Class<?> cl=Class.forName(replace);//获取改类的class对象if (isController(cl)){//是否有controller注解if (isRequestMapping(cl)){//是否有requestMapping注解RequestMapping requestMapping=getRequestMapping(cl);//获取requestmapping注解if (map.containsKey(requestMapping.value())){throw new RuntimeException("类多注解值:"+requestMapping.value());//跟之前扫描的名字冲突报错}else {map.put(requestMapping.value(),new HashMap<>());//类的requestMapping注解值和map字典放入字典中objMap.put(requestMapping.value(),cl.newInstance());//类的注解值和类对象放入字典中}Method[] declaredMethods=cl.getDeclaredMethods();//获取该对象的每一个方法对象for (Method declaredMethod : declaredMethods) {//遍历方法对象if (isRequestMapping(declaredMethod)){//判断该方法是否有requesting注解RequestMapping mapping=getRequestMapping(declaredMethod);//获取该方法的注解if (map.get(requestMapping.value()).containsKey(mapping.value())){//判断该类是否有相同的注解值,有就报错throw  new RuntimeException("方法多注解值:"+requestMapping.value());}else {map.get(requestMapping.value()).put(mapping.value(),declaredMethod);//没有就添加map对应类的方法字典中}}}}else {throw new RuntimeException("类无requestMapping");}}}catch (Exception e){e.printStackTrace();}}}public static void exec(String classPath,String methodPath){if (objMap.get(classPath)==null){//判断objmap字典中是否有这个类,没有则报错System.out.println("没有这个类 404");}else{if (map.get(classPath).get(methodPath)==null){//判断该类中是否有该方法System.out.println("没有这个方法 404");}else {try {//获取该类的该方法并且执行map.get(classPath).get(methodPath).invoke(objMap.get(classPath));} catch (IllegalAccessException e) {throw new RuntimeException(e);} catch (InvocationTargetException e) {throw new RuntimeException(e);}}}}private static List<String> traverseFolder2(String path){//创建main所在文件夹对象File file=new File(path);ArrayList<String> classPaths=new ArrayList<>();//创建数组,存放类路径if (file.exists()){//文件夹存在执行LinkedList<File> list=new LinkedList<>();//存放子文件夹路径以及子子文件夹数量File[] files=file.listFiles();//把main所在文件夹下的子文件夹和文件放入数组for (File file1 : files) {//遍历if (file1.isDirectory()){//判断是不是文件夹list.add(file1);//是放入子文件夹集合}else {classPaths.add(file1.getAbsolutePath());//文件则放入文件集合}}while (!list.isEmpty()){//子文件夹集合不为空,一直遍历,直到空为止File directory=list.removeFirst();//弹出第一个子文件夹对象File[] files1=directory.listFiles();for (File file1 : files1) {if (file1.isDirectory()){list.add(file1);//判断是否为文件夹,是则放入集合}else {classPaths.add(file1.getAbsolutePath());//文件则放入类集合}}}}return classPaths;}private static boolean isController(Class cl){Annotation annotation=cl.getAnnotation(Controller.class);if (annotation!=null){return true;}return false;}private static boolean isRequestMapping(Class cl){Annotation annotation=cl.getAnnotation(RequestMapping.class);if (annotation!=null){return true;}return false;}private static boolean isRequestMapping(Method method){Annotation annotation=method.getAnnotation(RequestMapping.class);if (annotation!=null){return true;}return false;}private static RequestMapping getRequestMapping(Class cl){Annotation annotation=cl.getAnnotation(RequestMapping.class);if (annotation instanceof RequestMapping){return (RequestMapping) annotation;}return null;}private static RequestMapping getRequestMapping(Method method){Annotation annotation = method.getAnnotation(RequestMapping.class);if(annotation instanceof  RequestMapping){return  (RequestMapping) annotation;}return null;}
}

4.启动类

package com.heaboy;import com.heaboy.mvc.HeaboyMvc;import java.util.Stack;public class Main {static {String path=Main.class.getResource("").getPath();//获取main方法的路径String packageName=Main.class.getPackage().getName();//获取main方法所在包的路径HeaboyMvc.scanner(path,packageName);//扫描main所在包中的类以及子包中的类}public static void main(String[] args) {HeaboyMvc.exec("","");HeaboyMvc.exec("test","index1");HeaboyMvc.exec("test","");HeaboyMvc.exec("test","asdfasdfasdf");HeaboyMvc.exec("test","");}
}

5.结果展示

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

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

相关文章

官宣定档!2025深圳电子展,开启全球招展工作

随着科技的飞速发展&#xff0c;电子信息产业已成为推动全球经济的重要力量。深圳&#xff0c;作为中国的硅谷&#xff0c;一直以来都是电子信息产业的前沿阵地。2025年&#xff0c;深圳电子展暨深圳国际电子信息博览会再次定档于4月份在深圳会展中心盛大召开&#xff0c;这不仅…

10元 DIY 一个柔性灯丝氛围灯

之前TikTok上特别火的线性氛围灯Augelight刚出来的时候一度卖到80多美金&#xff0c;国内1688也能到400多人民币。 随着各路国内厂商和DIY创客的跟进&#xff0c;功能变多的同时价格一路下滑&#xff0c;虽然有的质感的确感人&#xff0c;但是便宜啊。 甚至关注的up有把成本搞到…

python集成Bartender实现二维码打印

本文摘录于&#xff1a;https://blog.csdn.net/mynameisJW/article/details/105500773只是做学习备份之用&#xff0c;绝无抄袭之意&#xff0c;有疑惑请联系本人&#xff01; 这里上传我优化了一下的代码:https://download.csdn.net/download/chengdong1314/89522026 我这里弄…

Dungeonborne卡顿延迟怎么办?这样降低Dungeonborne延迟

Dungeonborne将第一人称的动作的即时性和经典的西幻RPG职业设计深度结合&#xff0c;带来无与伦比的游戏体验。玩家在游戏中扮演一位从神秘地牢中醒来的勇士&#xff0c;他必须面对各种未知的敌人和挑战&#xff0c;逐渐揭开自己的身世之谜。在这个充满魔法和奇迹的世界里&…

阶段三:项目开发---民航功能模块实现:任务18:指挥航空公司架次与延误率占比

任务描述 内 容&#xff1a;在前面的“使用Spark清洗统计业务数据并保存到数据库”任务中&#xff0c;已经通过Spark Streaming 清洗程序&#xff0c;将Kafka中Topic为“task_Aftn”的报文数据&#xff0c;经过数据清洗后&#xff0c;保存到了MySQL数据库中&#xff1b;本节任…

基于单片机的空调控制器的设计

摘 要 &#xff1a; 以单片机为核心的空调控制器因其体积小 、 成本低 、 功能强 、 简便易行而得到广泛应用 。 本设计通过 &#xff21;&#xff34;&#xff18;&#xff19;&#xff33;&#xff15;&#xff12; 控制&#xff24;&#xff33;&#xff11;&#xff18;&a…

【uniapp-ios】App端与webview端相互通信的方法以及注意事项

前言 在开发中&#xff0c;使用uniapp开发的项目开发效率是极高的&#xff0c;使用一套代码就能够同时在多端上线&#xff0c;像笔者之前写过的使用Flutter端和webview端之间的相互通信方法和问题&#xff0c;这种方式本质上实际上是h5和h5之间的通信&#xff0c;网上有非常多…

深度学习-基础网络组件介绍(六)

深度学习基础网络组件介绍 网络组件网络结构-全连接层激活函数常见激活函数-Sigmoid常见激活函数-tanh常见激活函数-Relu常见激活函数-Gelu常见激活函数-Softmax 损失函数损失函数-均方差损失函数-交叉熵&#xff08;Cross Entropy&#xff09; 网络组件 **释义&#xff1a;**…

基于docker的prometheus+grafana+altermanager+prometheus-webhook-dingtalk钉钉报警

一、各软件功能简介 prometheus&#xff1a;Prometheus(是由go语言(golang)开发)是一套开源的监控&报警&时间序列数 据库的组合。主要优点&#xff1a;外部依赖安装使用超简单、系统集成 多等 grafana&#xff1a;Grafana 是一款采用 go 语言编写的开源应用&#xff0…

电脑如何进行屏幕录制?快来看看这3种方法

在数字化浪潮席卷而来的今天&#xff0c;屏幕录制已不再是简单的视频记录&#xff0c;它演变成了一种表达、传播与创新的工具。传统的屏幕录制方法虽然经典简单&#xff0c;但已逐渐无法满足现代人对效率、品质和创意的追求。 所以&#xff0c;在这个充满变革与创新的时代&…

新能源汽车充电站远程监控系统S275钡铼技术无线RTU

新能源汽车充电站的远程监控系统在现代城市基础设施中扮演着至关重要的角色&#xff0c;而钡铼技术的S275无线RTU作为一款先进的物联网数据监测采集控制短信报警终端&#xff0c;为充电站的安全运行和高效管理提供了强大的技术支持。 技术特点和功能 钡铼S275采用了基于UCOSI…

上位机图像处理和嵌入式模块部署(mcu项目2:串口日志记录器)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 淘宝上面有一个商品蛮好玩的&#xff0c;那就是日志记录器。说是记录器&#xff0c;其实就是一个模块&#xff0c;这个模块的输入是一个ttl串口&am…

基于Java+SpringMvc+Vue技术的智慧校园系统设计与实现

博主介绍&#xff1a;硕士研究生&#xff0c;专注于信息化技术领域开发与管理&#xff0c;会使用java、标准c/c等开发语言&#xff0c;以及毕业项目实战✌ 从事基于java BS架构、CS架构、c/c 编程工作近16年&#xff0c;拥有近12年的管理工作经验&#xff0c;拥有较丰富的技术架…

PHP工单预约表单系统小程序源码

&#x1f527;【高效办公新利器】工单预约表单系统大揭秘 &#x1f4bc;【一键提交&#xff0c;工单管理新高度】 你还在为繁琐的工单提交流程头疼吗&#xff1f;工单预约表单系统&#xff0c;让你的工单管理步入高效时代&#xff01;只需简单几步&#xff0c;填写必要信息&a…

机器学习中的可解释性

「AI秘籍」系列课程&#xff1a; 人工智能应用数学基础 人工智能Python基础 人工智能基础核心知识 人工智能BI核心知识 人工智能CV核心知识 为什么我们需要了解模型如何进行预测 我们是否应该始终信任表现良好的模型&#xff1f;模型可能会拒绝你的抵押贷款申请或诊断你患…

高性能Python网络框架实现网络应用详解

概要 Python作为一种广泛使用的编程语言,其简洁易读的语法和强大的生态系统,使得它在Web开发领域占据重要位置。高性能的网络框架是构建高效网络应用的关键因素之一。本文将介绍几个高性能的Python网络框架,详细描述它们的特点、使用场景及具体示例代码,帮助高效实现网络应…

【linux高级IO(二)】多路转接之select详解

&#x1f493;博主CSDN主页:杭电码农-NEO&#x1f493;   ⏩专栏分类:Linux从入门到精通⏪   &#x1f69a;代码仓库:NEO的学习日记&#x1f69a;   &#x1f339;关注我&#x1faf5;带你学更多操作系统知识   &#x1f51d;&#x1f51d; Linux高级IO 1. 前言2. 初识s…

基于vue的可视化大屏

要提前准备一个xinyang.json文件 可以在这个网站下载 DataV.GeoAtlas地理小工具系列 (aliyun.com) 代码结构 总框架代码&#xff1a; <template><div><div class"center"><center-left /><center-map /><center-right /><…

Xterminal工具的安装与使用体验

Xterminal工具的安装与使用体验 一、Xterminal简介二、Xterminal核心特性三、Xterminal使用场景四、Xterminal下载地址五、Xterminal的基本使用5.1 设置仓库密码5.2 SSH连接5.3 Windows远程桌面5.4 笔记功能5.5 AI工具 六、总结 一、Xterminal简介 Xterminal是一款专为开发者设…

FastReport 指定sql 和修改 数据库连接地址的 工具类 :FastReportHelper

FastReport 指定sql 和修改 数据库连接地址的 工具类 &#xff1a;FastReportHelper 介绍核心代码&#xff1a;完整代码&#xff1a; 介绍 在FastReport中&#xff0c;经常会遇到需要给 sql 加条件的情况&#xff0c;或者给数据库地址做更换。 &#xff08;废话不多说&#x…