简单仿写MVC

news2024/9/25 3:20:16

代码地址(需要自取):mvc_Imitation: 简单仿写实现MVC (gitee.com)

项目目录

先把架子搭好

Controller注解

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @ interface Controller {
}

RequestMapping

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

HydController

@Controller
@RequestMapping("hyd")
public class HydController {
    @RequestMapping
    public  String index(){
        System.out.println("RequestMapping为“hyd, ”的方法已执行");
        return "";
    }
    @RequestMapping("hyd2")
    public  String index1(){
        System.out.println("RequestMapping为“hyd,hyd2”的方法已执行");
        return "";
    }
}

indexController

@Controller
@RequestMapping
public class IndexController {
    @RequestMapping
    public void index() {
        System.out.println("RequestMapping为“ , ”的方法已执行");
    }
}

Main

public class Main {
    static {
//        获取Main的路径
        String path = Main.class.getResource("").getPath();
//        获取Main的包名
        String packageName = Main.class.getPackage().getName();
        
        HydMVC.scanner(path, packageName);
    }

    public static void main(String[] args) {
        HydMVC.mehtod_go("","");
        HydMVC.mehtod_go("hyd","");
        HydMVC.mehtod_go("hyd","hyd2");
        HydMVC.mehtod_go("232323","23131");
        HydMVC.mehtod_go("hyd","23131");
    }

}

HydMVC

public class HydMVC {
//    存放 一级注解-二级注解-方法 的map
    private static HashMap<String,HashMap<String, Method>> map_method = new HashMap<>();
//    存放 一级注解-类的实例化对象 的map
    private static HashMap<String, Object> map_object = new HashMap<>();

    /**
     * 方法执行函数
     * @param first_path 第一路径
     * @param second_path 第二路径
     */
    public static void mehtod_go(String first_path,String second_path){
//        如果map_object中没有fisrt_path,则不存在该注解的类
        if (map_object.get(first_path)==null){
            System.out.println("没有一个类有"+first_path+"注解");
        }else {
            if (map_method.get(first_path).get(second_path)==null){
                System.out.println(first_path+"下没有"+second_path+"注解"+"的方法");
            }else{
                try {
                    map_method.get(first_path).get(second_path).invoke(map_object.get(first_path));
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 扫描获取类实例化对象以及方法
     * @param path
     * @param packageName 包名
     */

    public static void scanner(String path,String packageName){
//        扫描当前所有的文件
        List<String> paths = traverseFolder2(path);
//        遍历拿到的文件路径
        for (String path1 : paths) {
//              path1为:C:\ttt\imitating_spring_mvc\out\production\imitating_spring_mvc\com\heaboy\IndexController.class
//              先拿到文件名 例:IndexController.class
            path1=path1.substring(path.length()-1);
            try{
                //            构建类名
//            因为可能存在多级路径,例如:www/IndexController.class,所以还需要进行一些小处理,不能直接拼接
//            File.separator代表文件分隔符
//            Matcher.quoteReplacement确保了文件分隔符在替换过程中被正确地转义,以防包含任何正则表达式的特殊字符。它返回一个适合用于正则表达式替换的字符串。
                String ClassName = packageName + "." + path1.replaceAll(Matcher.quoteReplacement(File.separator),".");
//            去掉文件名中的.class后缀
                String load_className = ClassName.replace(".class","");
//            通过类加载器加载类
                Class<?> cl = ClassLoader.getSystemClassLoader().loadClass(load_className);
//            用写好的检查注解方法(isController)判断cl是否有Controller注解
                if(isController(cl)){
//              用写好的检查注解方法(isRequestMapping)判断cl是否有RequestMapping注解
                    if (isRequestMapping(cl)){
//                    如果有就获取类上RequestMapping注解的实例
                        RequestMapping requestMapping_first = getRequestMapping(cl);
//                    判断map_method中是否已经存在了该一级注解
                        if (map_method.containsKey(requestMapping_first.value())){
//                        已经存在该一级注解,则抛出异常
                            throw new RuntimeException("包含多个注解:"+requestMapping_first.value());
                        }else {
//                        不存在,添加至map_method中
                            map_method.put(requestMapping_first.value(),new HashMap<>());
//                        添加类的实例化对象到
                            map_object.put(requestMapping_first.value(),cl.newInstance());
                        }
//                    获取类中所有的方法
                        Method[] declareMethods = cl.getDeclaredMethods();
//                    遍历所有方法
                        for (Method method : declareMethods) {
                            if (isRequestMapping(method)){
                                RequestMapping requestMapping_second = getRequestMapping(method);
//                            判断该二级注解是否已经存在
                                if (map_method.get(requestMapping_first.value()).containsKey(requestMapping_second.value())){
//                                存在抛出错误
                                    throw new RuntimeException("方法注解已经存在:"+requestMapping_second.value());
                                }else {
//                                不存在就将方法放入map_method
                                    map_method.get(requestMapping_first.value()).put(requestMapping_second.value(),method);
                                }
                            }
                        }
                    }else{
                        throw new RuntimeException("该类有没RequestMapping注解");
                    }
                }
            }catch (Exception e){
                System.out.println(e);
            }
        }

    }



    /**
     * 扫描文件
     * @param path 绝对路径
     * @return List<String> 文件绝对路径集合
     * C:\ttt\imitating_spring_mvc\out\production\imitating_spring_mvc\com\heaboy\IndexController.class
     */
    private static List<String> traverseFolder2(String path) {
//        当前路径下的文件和文件夹
        File file = new File(path);
//        返回的文件集合
        List<String> file_list = new ArrayList<>();

        if (file.exists()){
//            放文件夹
            LinkedList<File> list = new LinkedList<>();

//            存储过程中要处理的文件
            File[] files = file.listFiles();

            for (File file1 : files) {
//                如果当前文件是文件夹就把它放到list里面
                if (file1.isDirectory()){
                    list.add(file1);
                }else { //不是就将该文件的绝对路径放到返回列表中file_list
                    file_list.add(file1.getAbsolutePath());
                }
            }
//            申请一个临时变量
            File file_temp;
//            当存放文件夹的队列不为空时,执行以下操作
            while (!list.isEmpty()){
//                取出第一个文件夹来处理
                file_temp=list.removeFirst();
//                使用上面申请的FIle[]来存放file_temp中的文件
                files=file_temp.listFiles();
//                处理files中的文件,同上,文件夹放到list中,文件放到file_list中
                for (File file1 : files) {
                    if (file1.isDirectory()){
                        list.add(file1);
                    }else {
                        file_list.add(file1.getAbsolutePath());
                    }
                }
            }
        }else{
//            如果没有任何文件,则不做处理
        }
        return file_list;
    }

//    判断类是否有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;
    }
//    获取类的RequestMapping注解的实例
    private static RequestMapping getRequestMapping(Class<?> cl) {
        Annotation annotation = cl.getAnnotation(RequestMapping.class);
        if (annotation instanceof  RequestMapping){
            return (RequestMapping) annotation;
        }
        return null;
    }

    //    判断方法是否有RequestMapping注解
    private static boolean isRequestMapping(Method method) {
        Annotation annotation = method.getAnnotation(RequestMapping.class);
        if (annotation!=null){
            return true;
        }
        return false;
    }
//    获取方法上的RequestMapping注解的实例
    private static RequestMapping getRequestMapping(Method method) {
        Annotation annotation  = method.getAnnotation(RequestMapping.class);
        if (annotation instanceof RequestMapping){
            return (RequestMapping) annotation;
        }
        return null;
    }

}

整体思路流程,先对路径下的文件进行扫描,拿到.class后缀的文件,然后根据不同的注解进行不同的操作,将实例化对象和方法都存到map中,再从map中获取调用。具体详细的解释可以查看代码及其注释。

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

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

相关文章

走拼箱货必看海运拼箱的实用技巧

在国际海运运输中&#xff0c;海运拼箱适用于货物数量较少或体积不足以填满整个集装箱的情况。 海运拼箱货物通常由物流公司或货代进行组织和管理。多个货主的货物通过合理拼装&#xff0c;使集装箱空间得到充分利用。 那么&#xff0c;在海运拼箱和整柜有哪些不同&#xff0c…

Xilinx Vitis 2020工程源目录修改

目录 1 背景2 分析3 解决4 使用4.1 修改路径4.2 编译工程4.2.1 清理工程4.2.2 编译工程 1 背景 Xilinx Vitis可以做standalone程序开发,不过其工程中使用的路径为绝对路径。工程更换位置后编译将会显示错误。例如&#xff1a;源目录为D:/work,复制到同事电脑上放到C:/work(同事…

无忧易售:在线刊登配备定价计算器,精准定价赢市场

在跨境电商的浩瀚宇宙里&#xff0c;精准定价是通往成功的关键钥匙。无忧易售&#xff0c;推出在线产品刊登页面的定价计算器功能&#xff0c;精准定价&#xff0c;轻松管理&#xff0c;让您的商品在海外市场脱颖而出&#xff0c;让每一次销售都精准高效&#xff0c;利润满满。…

Selenium 的基本操作你知道哪些?

1. 前言 今天的推文&#xff0c;我们就来说说看&#xff0c;怎么实现模拟真人去打开微信读书网站。 2.需求分析和准备 整体的需求大致可以分为以下步骤&#xff1a; 打开chrome浏览器 打开百度网页 搜索“微信读书” 点击进入“微信读书”官网 搜索关键词“长安的荔枝” 点…

浮动刹车盘和固定刹车盘有什么区别

在讨论刹车系统的设计理念时&#xff0c;浮动和固定刹车盘无疑是两个重要的分支。 它们各自拥有独特的设计哲学、工作原理以及适用场景&#xff0c;这些差异直接影响到了制动系统的性能和耐久性。 浮动刹车盘和固定刹车盘在设计和工作原理上有显著的区别&#xff0c;主要体现在…

现代化木工装备建设新颖校园木工创客室

校园木工创客室是一个集木工制作、创意设计、科技融合与教育实践于一体的多功能空间。它为学生提供了一个动手实践、创新创造的平台&#xff0c;旨在培养学生的动手能力、创新思维、解决问题的能力以及团队协作能力。 木工创客室的设备选择应综合考虑需求、预算、品牌、质量、安…

【源码下载】瓦房店农村电商大数据平台模板

技术详细实现可在评论区留言。 概述 用 echarts 和 jquery 实现的大屏模板效果。 部分代码展示&#xff0c;访问 dt.sim3d.cn 获取源码&#xff1a; (function($){$.extend({initMapChartPath : function(options){var defs {domId : ,mapName:china,mapCenter:["5…

saas lims系统:适合中小检测机构的实验室管理系统

目前市面上的LIMS系统分为两种&#xff1a;一种是传统的LIMS系统&#xff0c;一次性买断&#xff0c;配置服务器&#xff0c;成本相对来说是比较高的。还有一种就是以白码LIMS云平台为代表的&#xff0c;基于SaaS模式的LIMS系统。白码LIMS系统提供saas模式购买&#xff0c;帮助…

网络安全设备——探针

网络安全设备探针是一种专门用于网络安全领域的工具&#xff0c;它通过对网络流量进行监控和分析&#xff0c;帮助发现和防止网络攻击。以下是对网络安全设备探针的详细解释&#xff1a; 定义与功能 定义&#xff1a;网络安全设备探针是一种设备或软件&#xff0c;它通过捕获…

第58期 | GPTSecurity周报

GPTSecurity是一个涵盖了前沿学术研究和实践经验分享的社区&#xff0c;集成了生成预训练Transformer&#xff08;GPT&#xff09;、人工智能生成内容&#xff08;AIGC&#xff09;以及大语言模型&#xff08;LLM&#xff09;等安全领域应用的知识。在这里&#xff0c;您可以找…

短信群发精准营销策略全解析

短信群发作为传统而高效的营销手段&#xff0c;其效果却常因缺乏精准性而大打折扣。要实现短信群发的精准营销&#xff0c;关键在于两大核心要素与选择合适的平台。 一、精准营销的两大核心 1.数据细分&#xff0c;精准定位 在启动短信群发前&#xff0c;企业需…

基于JAVA+SpringBoot+Vue的社区普法平台

✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取项目下载方式&#x1f345; 一、项目背景介绍&#xff1a; 社区普法平台旨在为社…

【结构性型模式-适配器模式】

定义 将一个类的接口转换成客户希望的另外一个接口&#xff0c;使得原本由于接口不兼容而不能一起工作的那些类能一起工作。 适配器模式分为类适配器模式和对象适配器模式&#xff0c;前者类之间的耦合度比后者高&#xff0c;且要求程序员了解现有组件库中的相关组件的内部结…

道达尔远景首个光储项目圆满收官,助力纺织业绿色转型

近日&#xff0c;由道达尔远景&#xff08;TEESS&#xff09;开发、设计、建设并运营的德州夏仁津和纺织分布式光储项目顺利并网发电。通过光伏发电与储能系统的有机结合&#xff0c;不仅满足了纺织厂的用电需求&#xff0c;也为纺织业的绿色转型注入了新动力。 我国是全球最大…

如何使用ParaView可视化工具来绘制点云数据的3D点云图像(亲测好用)

如何使用ParaView来绘制点云数据。以下是如何将你的数据导入ParaView并进行可视化的步骤 一、准备数据 首先&#xff0c;你需要将你的数据转换为ParaView可以读取的格式。ParaView支持多种文件格式&#xff0c;其中最常见的是.vtk和.csv格式。为了简单起见&#xff0c;这里我…

【Gradle】(三)详细聊聊依赖管理:坐标、依赖配置、依赖传递、依赖冲突

文章目录 1.概述2.依赖管理2.1.坐标2.2.依赖的基本概念2.3.依赖配置&#xff08;Dependency configurations&#xff09;2.3.1.依赖路径2.3.2.依赖配置与依赖路径的关联 2.4.依赖传递2.4.1.准备工作2.4.2.运行时依赖传递jar包生成与依赖配置依赖树打印使用 Dependency Analyzer…

mybatilsplaus 常用注解

官网地址 baomidou注解配置

数据高效交互丨DolphinDB Redis 插件使用指南

DolphinDB 是一个高性能的分布式数据库。通过 Redis 插件&#xff0c;DolphinDB 用户可以轻松地与 Redis 数据库进行交互。用户不仅可以从 DolphinDB 向 Redis 发送数据&#xff0c;实现高速的数据写入操作&#xff1b;还可以从 Redis 读取数据&#xff0c;将实时数据流集成到 …

关于嵌入式系统中的LED控制程序的一篇爽文

嵌入式系统中的LED控制程序 在嵌入式系统中控制LED是一个很常见的任务&#xff0c;可以用于指示状态、显示信息等。我们将使用C语言编写一个简单的LED控制程序&#xff0c;该程序将控制一个虚拟的LED&#xff0c;但可以根据需要将其扩展到实际的硬件上。 准备工作 在开始之前…

灯塔音乐网,灯塔音乐下载官网

音乐&#xff0c;这个无形的艺术&#xff0c;自古以来就伴随着人类的生活&#xff0c;成为了我们表达情感、沟通思想、寻求共鸣的重要桥梁。在我们的日常生活中&#xff0c;音乐无处不在&#xff0c;它不仅仅是一种娱乐方式&#xff0c;更是一种生活态度&#xff0c;一种精神寄…