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.结果展示