欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

SpringMVC手写

程序员文章站 2022-07-15 11:21:51
...

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);
    }

转载于:https://www.jianshu.com/p/1c1ee8a2163c

上一篇: 手写SpringMVC

下一篇: 手写 springmvc