SpringMVC手写

作者: aix91 | 来源:发表于2019-01-20 16:21 被阅读0次

    1. 自定义Controller 和RequestMapping注解

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

    2. 定义容器,用来存储实例化bean,url以及方法

      //用来存储包下面的注解bean
        private ConcurrentHashMap<String, Object> springMvcBeans = new ConcurrentHashMap<>();
    //存储RequestMapping注解的bean 
        private ConcurrentHashMap<String, Object> urlBeans = new ConcurrentHashMap<>();
    //存储RequestMapping注解的方法
        private ConcurrentHashMap<String, String> methodBeans = new ConcurrentHashMap<>();
    

    3. 初始化容器

    • 初始化bean容器
    public void findMVCClasses(List<Class<?>> classes)     
    throws IllegalAccessException, InstantiationException, ClassNotFoundException {
            for (Class<?> clazz : classes) {
                ExtController controller = clazz.getDeclaredAnnotation(ExtController.class);
                if (controller != null) {
                    String beanName = ClassUtil.toLowerCaseFirstOne(clazz.getSimpleName());
                    Object bean = ClassUtil.newInstance(clazz.getName(), new HashMap<>());
                    springMvcBeans.put(beanName, bean);
                }
            }
        }
    
    • 初始化urlBean容器, 以及urlMethod容器
     public void findHandleMapping() {
            springMvcBeans.entrySet().forEach(entry -> {
                Object bean = entry.getValue();
                Class<?> classInfo = bean.getClass();
                ExRequestMapping requestMapping = classInfo.getDeclaredAnnotation(ExRequestMapping.class);
                String baseUrl = "";
                if (requestMapping != null) {
                    baseUrl = requestMapping.value();
                }
                Method[] methods = classInfo.getDeclaredMethods();
                for (Method method : methods) {
                    ExRequestMapping exRequestMapping = method.getDeclaredAnnotation(ExRequestMapping.class);
                    if (exRequestMapping != null) {
                        String url = baseUrl + exRequestMapping.value();
                        urlBeans.put(url, bean);
                        methodBeans.put(url, method.getName());
                    }
                }
            });
        }
    

    4. 接受请求,找到请求对应的bean和方法

     @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            String url = req.getRequestURI();
            Object obj = urlBeans.get(url);
            if (obj == null) {
                resp.getWriter().println("404");
                return;
            }
            String methodName = methodBeans.get(url);
            if (methodName == null) {
                resp.getWriter().println("Can't find such method");
                return;
            }
            extResourceViewResolver(invokeMethod(obj, methodName), req, resp);
        }
    
    • 利用反射invoke方法
        public String invokeMethod(Object obj, String methodName) {
            String result = null;
            try {
                Class<?> classInfo = obj.getClass();
                result = (String) classInfo.getDeclaredMethod(methodName).invoke(obj);
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            }
            return result;
        }
    
    • 定义ViewResolver
    void extResourceViewResolver(String pathName, HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
            String prefix = "/";
            String suffix = ".jsp";
            req.getRequestDispatcher(prefix + pathName + suffix).forward(req, res);
        }
    

    相关文章

      网友评论

        本文标题:SpringMVC手写

        本文链接:https://www.haomeiwen.com/subject/bqezdqtx.html