SpringMVC简单仿写

之前我分享过SpringMVC的基本原理与配置(原文链接:https://blog.csdn.net/L170311/article/details/129339120),为了更深层次的学习,精益求精,手动仿写了一个MVC原理实现demo,一起学习一下吧


结构目录:

 两个自定义注解,两个Controller,核心ImitateSpringMVC,以及测试Main

 @Controller和@RequestMapping

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Controller {}@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE,ElementType.METHOD})
public @interface RequestMapping {String value() default "";
}

@Documented     

        该注解的作用就是在生产文档的时候,保留自定义注解的存在,例如:

         -d doc Test.java ; 如果Test.java中有自定义的注解,然后该注解上面有@Documented,那么生成的文档中就会包含自定义注解部分,反之就没有。

@Retention(RetentionPolicy.RUNTIME)

    
@Target(ElementType.TYPE)

        target英文有目标、目的的意思。 @Target在java中是注释类。@Target作用于修饰的注释可以修饰的类型范围

        @Target包含一个ElementType[]元素类型的数组。ElementType[]数组值value,表明Target修饰的注释可以修饰的类型范围。ElementType枚举值包含方法、属性、类等等。

        ANNOTATION_TYPE: 注解只能修饰注解,不能修饰其他的东西

        CONSTRUCTOR: 注解只能修饰构造方法

        FIELD: 注解只能修饰属性(成员变量) 字段加解密注解标记拦截

        LOCAL_VARIABLE: 注解只能修饰局部变量

        METHOD: 注解只能修饰方法 对应的方法进行拦截

        PACKAGE: 注解只能修饰包

        PARAMETER: 注解只能修饰方法的参数

        TYPE: 注解只能修饰类、接口、枚举

 TestController

@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 "";}
}

核心:ImitateSpringMVC

public class ImitateSpringMVC {private static HashMap<String, Map<String, Method>> map=new HashMap<>();private static HashMap<String, Object> objMap=new HashMap<>();public static void exec(String classPath,String methodPath){if(objMap.get(classPath)==null){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) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();}}}}public static void scanner(String path,String packageName){//遍历当前路径下的所有文件List<String> paths = traverseFolder2(path);for (String p : paths) {p=p.substring(path.length()-1);try {String className=packageName+"."+p.replaceAll( Matcher.quoteReplacement(File.separator),".");String replace = className.replace(".class", "");//通过类加载器加载类信息Class<?> cl = ClassLoader.getSystemClassLoader().loadClass(replace);if(isController(cl)){if(isRequestMapping(cl)){//获得我们设置在@RequestMapping里的值RequestMapping requestMapping = getRequestMapping(cl);//如果注解值重复,抛异常if(map.containsKey(requestMapping.value())){throw  new RuntimeException("类多注解值:"+requestMapping.value());}else {map.put(requestMapping.value(),new HashMap<>());objMap.put(requestMapping.value(),cl.newInstance());}//获得当前类对象声明的所有方法Method[] declaredMethods = cl.getDeclaredMethods();for (Method declaredMethod : declaredMethods) {//遍历,判定方法是否带有@RequestMapping注解if(isRequestMapping(declaredMethod)){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<K,V>中k是我们获取到类对象的@RequestMapping的值,V是类对象方法的@RequestMapping的值,组成的一个集合}}}}else {throw  new RuntimeException("类无requestMapping");}}} catch (ClassNotFoundException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (InstantiationException e) {e.printStackTrace();}}}//判定类文件是否带有@Controller注解private static boolean isController(Class cl){Annotation annotation = cl.getAnnotation(Controller.class);if(annotation!=null){return  true;}return false;}//判定类文件是否带有@RequestMapping注解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;}private static List<String> traverseFolder2(String path) {File file = new File(path);List<String> classFiles=new ArrayList<>();//如果文件存在,开始遍历if (file.exists()) {LinkedList<File> list = new LinkedList<File>();File[] files = file.listFiles();for (File file2 : files) {//如果文件是文件夹的形式,放入listif (file2.isDirectory()) {list.add(file2);} else {classFiles.add(file2.getAbsolutePath());}}File temp_file;while (!list.isEmpty()) {temp_file = list.removeFirst();files = temp_file.listFiles();for (File file2 : files) {if (file2.isDirectory()) {list.add(file2);} else {classFiles.add(file2.getAbsolutePath());}}}} else {}return classFiles;}
}

 

IndexController

@Controller
@RequestMapping
public class IndexController {@RequestMappingpublic  void index(){System.out.println("index -> index");}}

 Main

public class Main {static {//获得当前类的路径String path = Main.class.getResource("").getPath();//获得当前类的包名String packageName = Main.class.getPackage().getName();//传入到MVC的方法中ImitateSpringMVC.scanner(path,packageName);}public static void main(String[] args) {ImitateSpringMVC.exec("","");ImitateSpringMVC.exec("test","index1");ImitateSpringMVC.exec("test","");System.out.println("SpringMVC!");}}

demo已上传gitee平台:https://gitee.com/dont-live-in-the-past/spring-mvc-simple-imitation

 

 

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

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

相关文章

Netty :仿写微信 IM 即时通讯系统

前言 最近公司要自研聊天系统,开始撸代码… 仿微信IM系统简介 (1)客户端使用Netty程序实现逻辑 解析控制台指令(譬如发送消息或者建立群聊等指令)->基于控制台输入创建指令对象->协议的编码(通过自定义二进制协议将指令对象封装成二进制); 接收服务端数据拆包粘包处理…

python如何仿写文章_tensorflow - RNN学习文章的风格去仿写

1 . 能干什么 在知乎&#xff0c;博客上面会看到有人分享自己的一些有意思的项目&#xff0c;比如下面这些&#xff0c;用rnn学习一个诗歌&#xff0c;散文&#xff0c;党章&#xff0c;小说什么的。然后&#xff0c;在自己生成一些东西。比如&#xff0c;下面的这两个例子。作…

html仿写百度,vue 简单仿写百度搜索

vue .grey{ background: #CCC; height: 25px; } ul,li{ margin: 0; padding: 0; list-style-type:none; margin-left: 65px; width: 306px; } .dialog{ margin-left: 10px; margin-top: 30px; width: 300px; height: 25px; } .note{ margin-left: 130px; } window.οnlοadfunc…

html搜狐热搜列表仿写,GRE高分范文不能看过就算 学会仿写才能带来真正提高

可以说所有的写作都是从模仿开始。GRE作文同样不例外。通过参考他人的好文章&#xff0c;学习别人的写法&#xff0c;最后写出自己的文章是非常实用的作文学习方式。不过&#xff0c;模仿也需要讲究方法&#xff0c;单纯模仿并不会让大家有太多的收获。掌握方法才能有效提升自身…

PHP仿写网站,手机网站仿写0910

最近有点儿忙,这个作业交的有点儿晚了,但这个作业是看了老师讲解后一口气写出来的代码,不像以前的作业要反复的看老师的课件才完成的。通过这一段前端知识的学习我最大的收获就是学会用开发者工具去看一个网站的代码了,可以看懂大多数的网页的静态代码了,会逐步的分析一个…

绕过接口参数签名验证

在一些关键业务接口,系统通常会对请求参数进行签名验证,一旦篡改参数服务端就会提示签名校验失败。在黑盒渗透过程中,如果没办法绕过签名校验,那么就无法进一步深入。 微信小程序的前端代码很容易被反编译,一旦签名加密算法和密钥暴漏,找到参数的排序规则,那么就可以篡改…

在Mac电脑中轻松打开终端程序的快捷方法

命令行窗口实际就是我们常用的终端程序&#xff0c;命令行窗口在高级用户上&#xff0c;是经常用到的&#xff0c;但在Mac电脑中打开终端程序是比较麻烦的&#xff0c;下面分享几个快捷方法可以轻松打开终端程序。 方法一、 1、在Mac键盘上按住commandspace&#xff0c; 2、在…

【mac】关于终端上使用的快捷键

【mac】关于终端上使用的快捷键 清理行&#xff1a;您可以使用Ctrl U清理到开头。清理线路&#xff1a;Ctrl E Ctrl U擦拭终端中的当前线路清理线路&#xff1a;Ctrl A Ctrl K擦拭终端中的当前线路取消当前的命令行/行&#xff1a;Ctrl C。调用已删除的命令&#xff1a;Ctrl Y&…

mac之把打开终端设置快捷键为Ctrl+Alt+T

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程 1、在Automator.app中创建一个AppleScript Finder&#xff0d;>应用程序->Automator打开Automator.app&#xff0c;打开Automator后…

【苹果推群发iMessage推】软件安装它起首将消息发送到Apple Push服务器,而后Apple Push服务器将消息发送到装配了应用程序的手机

推荐内容IMESSGAE相关 作者推荐内容iMessage苹果推软件 *** 点击即可查看作者要求内容信息作者推荐内容1.家庭推内容 *** 点击即可查看作者要求内容信息作者推荐内容2.相册推 *** 点击即可查看作者要求内容信息作者推荐内容3.日历推 *** 点击即可查看作者要求内容信息作者推荐…

ios13快捷指令怎么设置

在ios13系统中新增了很多值得一提的功能&#xff0c;可以帮助更加简单化的使用iphone手机&#xff0c;而在手机上也可以实现喊一句就能帮你进入该功能&#xff0c;那么ios13快捷指令怎么设置呢&#xff1f;下面就为大家带来ios13快捷指令设置方法&#xff0c;想知道的一起来了解…

IOS中通过快捷捷径打开场所码或者健康码

说明 本文标题其实应该叫“使用快捷捷径打开任意微信小程序页面”&#xff0c;因为本质上这篇文章就是说明如何在获取微信小程序任意界面的页面路径&#xff0c;以及通过Universal link在微信中打开对应页面的方法&#xff08;本文使用“跨时空”APP来达到此目的&#xff09;。…

小度送音箱,这是只属于开发者的福利

人工智能&#xff0c;将带给人们一个新的场景和蓝海市场 2019年的第一天&#xff0c;李彦宏以人工智能领域嘉宾的身份做客央视元旦特别节目《放歌新时代》&#xff0c;与主持人康辉一起展开了一场关于人工智能的对话&#xff1a;对话中李彦宏提到&#xff0c;2019年是人工智能全…

7个月后再测「小度在家」,已然超出音箱属性的未来新物种

作者&#xff5c;震霆 出品&#xff5c;遇见人工智能 公众号&#xff5c;GOwithAI 双十一的节奏你感受到了吗&#xff1f; 虽然离正日子还有6天&#xff0c;就连天猫和京东都还没到高潮&#xff0c;百度却抢先截胡&#xff0c;抛出了个大动作。 有这么一款当红明星AI产…

使用小度音箱+Blinker控制ESP01S Relay继电器模块

一. 使用ESP01S模块&#xff0c;PIN脚定义如下&#xff1a; 管脚功能如下&#xff1a; ESP01S模块原理图&#xff1a; ESP01S模块比ESP01模块做了以下优化&#xff1a; LED灯的管脚发生变化&#xff0c;由ESP01的TXD0变成ESP01s的GPIO2引脚&#xff1b;ESP01s模块的IO0、RST、…

小度智能音箱2红外版测评和拆机

小度智能音箱 2 红外版测评和拆机 买的小度智能音箱今天到货了&#xff0c;哈哈。这个版本支持红外&#xff0c;可以控制家里老家电。之前买过的小爱mini&#xff0c;天猫精灵&#xff0c;白色小度音箱1代&#xff0c;现在基本都在吃灰了&#xff0c;卖二手音箱啦&#xff5e;…

用小爱,小度语音控制家里的灯,无网络时,不影响物理开关

贝壳物联和小度&#xff0c;小爱的完美结合 亮点材料接线注册贝壳物联ArduinoIDE 安装程序编写烧录巴法云微信推送巴法云控制设置微信小程序控制设备小度音箱&#xff0c;小爱绑定和语音控制关于内网穿透和程序的在线更新 亮点 0.支持开关状态推送到微信 1.成本不超过20块&…

小度、天猫精灵、华为哪款智能音箱值得推荐?

随着智能家居的势头比较火热&#xff0c;各大智能厂商纷纷开启抓住了智能音箱市场的第一波红利&#xff0c;迅速入场布局分一杯羹。那么今天我们就来聊一聊&#xff0c;市场上有哪些主流的智能音箱品牌&#xff1f; 目前&#xff0c;大部分智能音箱在语音交互和内容播放上都差…

小度计算机模式,小度怎么连接电脑_小度智能音箱连接电脑的详细操作步骤

如果讲智能音箱哪家卖得好&#xff0c;小度肯定是排在前一二的&#xff0c;而大家不知道的是小度不仅可以连接手机&#xff0c;还可以连接电脑&#xff0c;那么小度智能音箱怎么与电脑配对和连接呢&#xff0c;为了给大家一些参考&#xff0c;下面智能手机网小编就带来了教小度…