仿写springmvc(反射)

仿写springmvc(反射),第1张

仿写springmvc(反射)

Main.class
定义了程序启动的入口,在实际中由tomcat启动main方法

public class Main {
    static {
        String path = Main.class.getResource("").getPath();//获取类加载的根路径
        String packageName = Main.class.getPackage().getName();//返回包名
        HeaboyMvc.scanner(path,packageName);//对所有此路径下的java类进行扫描并处理
    }

    public static void main(String[] args) {
        HeaboyMvc.exec("test","index1"); //controller+method的requestmapping
        HeaboyMvc.exec("test","");
        System.out.println("Hello World!");
    }
}

controller示例

@Controller
@RequestMapping("test")
public class TestController {
    @RequestMapping
    public  String index(){
        System.out.println("test->index");
        return "";
    }
    @RequestMapping("index1")
    public  String index1(){
        System.out.println("test->index1");
        return "";
    }
}

mvc工具类(模拟mvc的反射)

public class HeaboyMvc {
    private static HashMap> map=new HashMap<>();//存储mapping与方法对象
    private static HashMap objMap=new HashMap<>();//存储类的对象示例,反射产生
    public static void exec(String classPath,String methodPath){//执行具体方法(输入requestmapping)
        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));//对方法进行invoke,使方法执行
                } 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的方法获取类对象(Class对象)
                Class cl = ClassLoader.getSystemClassLoader().loadClass(replace);//通过系统类加载器加载类获得类对象
                if(isController(cl)){//下面进行判断,对类上的注解进行分析处理
                    if(isRequestMapping(cl)){
                        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());//通过反射为类创建实例对象,需要在invoke时传入此对象
                        }
                        Method[] declaredMethods = cl.getDeclaredMethods();
                        for (Method declaredMethod : declaredMethods) {
                            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);//为类的每个方法对象都存入hash,方便调用
                                }
                            }
                        }
                    }else {
                        throw  new RuntimeException("类无requestMapping");
                    }
                }
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InstantiationException e) {
                e.printStackTrace();
            }
        }


    }

    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;
    }
    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) {
                if (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;
    }
}


可以看到,在执行具体方法前,在main所在类中的static代码块先执行了扫描 *** 作,将所有与main在同一路径下的类进行递归式的扫描,确认其注解是否存在以及是否合法(不可以多个mapping),将合法的存入hashmap,一个存放<类mapping,类实例>,一个存放<类mapping,<方法mapping,method对象>,这样可以在调用时很快的找到方法,如不存在则提示报错(访问不到)。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5708245.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存