手写 java框架_手写SpringMVC 框架

1 packagecom.tjt.springmvc;2

3

4 importjavax.servlet.ServletConfig;5 importjavax.servlet.ServletException;6 importjavax.servlet.http.HttpServlet;7 importjavax.servlet.http.HttpServletRequest;8 importjavax.servlet.http.HttpServletResponse;9 importjava.io.IOException;10 importjava.lang.reflect.InvocationTargetException;11 importjava.lang.reflect.Method;12 importjava.util.List;13 importjava.util.Map;14 importjava.util.Objects;15 importjava.util.concurrent.ConcurrentHashMap;16

17

18

19 /**

20 * DispatcherServlet 处理SpringMVC 框架流程21 * 主要流程:22 * 1、包扫描获取包下面所有的类23 * 2、初始化包下面所有的类24 * 3、初始化HandlerMapping 方法,将url 和方法对应上25 * 4、实现HttpServlet 重写doPost 方法26 *27 */

28 public class DispatcherServlet extendsHttpServlet {29

30 /**

31 * 部分静态常量32 */

33 private static String PACKAGE_CLASS_NULL_EX = "包扫描后的classes为null";34 private static String HTTP_NOT_EXIST = "sorry http is not exit 404";35 private static String METHOD_NOT_EXIST = "sorry method is not exit 404";36 private static String POINT_JSP = ".jsp";37 private static String LEFT_LINE = "/";38

39 /**

40 * 用于存放SpringMVC bean 的容器41 */

42 private ConcurrentHashMap mvcBeans = new ConcurrentHashMap<>();43 private ConcurrentHashMap mvcBeanUrl = new ConcurrentHashMap<>();44 private ConcurrentHashMap mvcMethodUrl = new ConcurrentHashMap<>();45 private static String PROJECT_PACKAGE_PATH = "com.tjt.springmvc";46

47

48 /**

49 * 按顺序初始化组件50 *@paramconfig51 */

52 @Override53 public voidinit(ServletConfig config) {54 String packagePath =PROJECT_PACKAGE_PATH;55 try{56 //1.进行报扫描获取当前包下面所有的类

57 List> classes =comscanPackage(packagePath);58 //2.初始化springmvcbean

59 initSpringMvcBean(classes);60 } catch(Exception e) {61 e.printStackTrace();62 }63 //3.将请求地址和方法进行映射

64 initHandMapping(mvcBeans);65 }66

67

68 /**

69 * 调用ClassUtils 工具类获取工程中所有的class70 *@parampackagePath71 *@return

72 *@throwsException73 */

74 public List> comscanPackage(String packagePath) throwsException {75 List> classes =ClassUtils.getClasses(packagePath);76 returnclasses;77 }78

79 /**

80 * 初始化SpringMVC bean81 *82 *@paramclasses83 *@throwsException84 */

85 public void initSpringMvcBean(List> classes) throwsException {86 /**

87 * 若包扫描出的classes 为空则直接抛异常88 */

89 if(classes.isEmpty()) {90 throw newException(PACKAGE_CLASS_NULL_EX);91 }92

93 /**

94 * 遍历所有classes 获取@MyController 注解95 */

96 for (Class>aClass : classes) {97 //获取被自定义注解的controller 将其初始化到自定义springmvc 容器中

98 MyController declaredAnnotation = aClass.getDeclaredAnnotation(MyController.class);99 if (declaredAnnotation != null) {100 //获取类的名字

101 String beanid =lowerFirstCapse(aClass.getSimpleName());102 //获取对象

103 Object beanObj =aClass.newInstance();104 //放入spring 容器

105 mvcBeans.put(beanid, beanObj);106 }107 }108

109 }110

111 /**

112 * 初始化HandlerMapping 方法113 *114 *@parammvcBeans115 */

116 public void initHandMapping(ConcurrentHashMapmvcBeans) {117 /**

118 * 遍历springmvc 获取注入的对象值119 */

120 for (Map.Entryentry : mvcBeans.entrySet()) {121 Object objValue =entry.getValue();122 Class> aClass =objValue.getClass();123 //获取当前类 判断其是否有自定义的requestMapping 注解

124 String mappingUrl = null;125 MyRequestMapping anRequestMapping = aClass.getDeclaredAnnotation(MyRequestMapping.class);126 if (anRequestMapping != null) {127 mappingUrl =anRequestMapping.value();128 }129 //获取当前类所有方法,判断方法上是否有注解

130 Method[] declaredMethods =aClass.getDeclaredMethods();131 /**

132 * 遍历注解133 */

134 for(Method method : declaredMethods) {135 MyRequestMapping methodDeclaredAnnotation = method.getDeclaredAnnotation(MyRequestMapping.class);136 if (methodDeclaredAnnotation != null) {137 String methodUrl =methodDeclaredAnnotation.value();138 mvcBeanUrl.put(mappingUrl +methodUrl, objValue);139 mvcMethodUrl.put(mappingUrl +methodUrl, method.getName());140 }141 }142

143 }144

145 }146

147 /**

148 *@paramstr149 *@return类名首字母小写150 */

151 public staticString lowerFirstCapse(String str) {152 char[] chars =str.toCharArray();153 chars[0] += 32;154 returnString.valueOf(chars);155

156 }157

158 /**

159 * doPost 请求160 *@paramreq161 *@paramresp162 *@throwsServletException163 *@throwsIOException164 */

165 @Override166 protected void doPost(HttpServletRequest req, HttpServletResponse resp) throwsServletException, IOException {167 try{168 /**

169 * 处理请求170 */

171 doServelt(req, resp);172 } catch(NoSuchMethodException e) {173 e.printStackTrace();174 } catch(InvocationTargetException e) {175 e.printStackTrace();176 } catch(IllegalAccessException e) {177 e.printStackTrace();178 }179 }180

181 /**

182 * doServelt 处理请求183 *@paramreq184 *@paramresp185 *@throwsIOException186 *@throwsNoSuchMethodException187 *@throwsInvocationTargetException188 *@throwsIllegalAccessException189 *@throwsServletException190 */

191 private void doServelt(HttpServletRequest req, HttpServletResponse resp) throwsIOException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, ServletException {192 //获取请求地址

193 String requestUrl =req.getRequestURI();194 //查找地址所对应bean

195 Object object =mvcBeanUrl.get(requestUrl);196 if(Objects.isNull(object)) {197 resp.getWriter().println(HTTP_NOT_EXIST);198 return;199 }200 //获取请求的方法

201 String methodName =mvcMethodUrl.get(requestUrl);202 if (methodName == null) {203 resp.getWriter().println(METHOD_NOT_EXIST);204 return;205 }206

207

208 //通过构反射执行方法

209 Class> aClass =object.getClass();210 Method method =aClass.getMethod(methodName);211

212 String invoke =(String) method.invoke(object);213 //获取后缀信息

214 String suffix =POINT_JSP;215 //页面目录地址

216 String prefix =LEFT_LINE;217 req.getRequestDispatcher(prefix + invoke +suffix).forward(req, resp);218

219

220

221

222 }223

224 /**

225 * doGet 请求226 *@paramreq227 *@paramresp228 *@throwsServletException229 *@throwsIOException230 */

231 @Override232 protected void doGet(HttpServletRequest req, HttpServletResponse resp) throwsServletException, IOException {233 this.doPost(req, resp);234 }235

236

237 }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值