SpringMVC简单仿写
创始人
2024-06-01 06:49:12
0

之前我分享过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> map=new HashMap<>();private static HashMap 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 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是我们获取到类对象的@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 traverseFolder2(String path) {File file = new File(path);List classFiles=new ArrayList<>();//如果文件存在,开始遍历if (file.exists()) {LinkedList list = new LinkedList();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

相关内容

热门资讯

喜欢穿一身黑的男生性格(喜欢穿... 今天百科达人给各位分享喜欢穿一身黑的男生性格的知识,其中也会对喜欢穿一身黑衣服的男人人好相处吗进行解...
发春是什么意思(思春和发春是什... 本篇文章极速百科给大家谈谈发春是什么意思,以及思春和发春是什么意思对应的知识点,希望对各位有所帮助,...
网络用语zl是什么意思(zl是... 今天给各位分享网络用语zl是什么意思的知识,其中也会对zl是啥意思是什么网络用语进行解释,如果能碰巧...
为什么酷狗音乐自己唱的歌不能下... 本篇文章极速百科小编给大家谈谈为什么酷狗音乐自己唱的歌不能下载到本地?,以及为什么酷狗下载的歌曲不是...
华为下载未安装的文件去哪找(华... 今天百科达人给各位分享华为下载未安装的文件去哪找的知识,其中也会对华为下载未安装的文件去哪找到进行解...
怎么往应用助手里添加应用(应用... 今天百科达人给各位分享怎么往应用助手里添加应用的知识,其中也会对应用助手怎么添加微信进行解释,如果能...
家里可以做假山养金鱼吗(假山能... 今天百科达人给各位分享家里可以做假山养金鱼吗的知识,其中也会对假山能放鱼缸里吗进行解释,如果能碰巧解...
一帆风顺二龙腾飞三阳开泰祝福语... 本篇文章极速百科给大家谈谈一帆风顺二龙腾飞三阳开泰祝福语,以及一帆风顺二龙腾飞三阳开泰祝福语结婚对应...
四分五裂是什么生肖什么动物(四... 本篇文章极速百科小编给大家谈谈四分五裂是什么生肖什么动物,以及四分五裂打一生肖是什么对应的知识点,希...
美团联名卡审核成功待激活(美团... 今天百科达人给各位分享美团联名卡审核成功待激活的知识,其中也会对美团联名卡审核未通过进行解释,如果能...