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