简单mvc---模拟Springmvc
1、注解篇
Auwowrited
package org.aaron.mvc.annaotation; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Repeatable; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target({ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface AaronAutowrited { String value() default ""; }
Controller
package org.aaron.mvc.annaotation; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Repeatable; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface AaronController { String value() default ""; }
RequestMapping
package org.aaron.mvc.annaotation; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Repeatable; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target({ElementType.TYPE,ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface AaronRequestMapping { String value() default ""; }
RequestParam
package org.aaron.mvc.annaotation; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Repeatable; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target({ElementType.PARAMETER}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface AaronRequestParam { String value() default ""; }
Service
package org.aaron.mvc.annaotation; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Repeatable; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface AaronService { String value() default ""; }
2、DispatcherServlet
package org.aaron.mvc.servlet; import java.io.File; import java.io.IOException; import java.lang.annotation.Annotation; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.URL; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.aaron.mvc.annaotation.AaronAutowrited; import org.aaron.mvc.annaotation.AaronController; import org.aaron.mvc.annaotation.AaronRequestMapping; import org.aaron.mvc.annaotation.AaronRequestParam; import org.aaron.mvc.annaotation.AaronService; import org.omg.CORBA.Request; public class DispatcherServlet extends HttpServlet { List<String> classNames = new ArrayList<String>();// 全类名路径 // //org.aaron.mvc.service.impl+类名 Map<String,Object> beans = new HashMap<>(); Map<String,Object> handlerMap = new HashMap<>(); /** * */ private static final long serialVersionUID = 1L; public void init(ServletConfig config) { // ioc // 扫描所有的bean----->扫描所有的class文件 scanPackage("org.aaron"); // spring的做法是写在配置文件中 // 根据类创建对象 doInstance(); doIoc(); buildUrlMapping();//根据url 建立关系 method } // 扫描文件 private void scanPackage(String basePackage) { URL url = this.getClass().getClassLoader().getResource("/" + basePackage.replaceAll("\\.", "/"));// 获取工作空间的编译路径 System.err.println(url); String fileStr = url.getFile(); File file = new File(fileStr);// 拿到目录下的文件和文件夹 String[] filesStr = file.list(); // Aaron for (String path : filesStr) { File filePath = new File(fileStr + path);// org.aaron.mvc if (filePath.isDirectory()) {// 判断是文件还是文件夹 文件夹 递归继续找 scanPackage(basePackage + "." + path); } else { classNames.add(basePackage + "." + filePath.getName());// org.aaron.mvc.xxx.xxxx.class } } } // 根据扫描的类名 实例化 private void doInstance() { if (classNames.size() <= 0) { System.err.println("扫描失败"); return; } // 遍历 扫描到class文件 for (String className : classNames) { String cn = className.replace(".class", ""); try { Class<?> clazz = Class.forName(cn); // 获取到org.aaron. if (clazz.isAnnotationPresent(AaronController.class)) {// 判断是不是有控制场注解 Object instance = clazz.newInstance();// 创建类 实例化的对象 AaronRequestMapping requestMapping = clazz.getAnnotation(AaronRequestMapping.class);//拿到 mapping 注解 String rm = requestMapping.value();//获取到mapping的value beans.put(rm, instance);// }else if (clazz.isAnnotationPresent(AaronService.class)){ AaronService aaronService = clazz.getAnnotation(AaronService.class); Object instance = clazz.newInstance(); beans.put(aaronService.value(),instance);// }else{ continue; } } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } //把service 注入到Controller public void doIoc(){ if(beans.entrySet().size()<=0){ System.err.println("没有实例化的类"); } //遍历map的实例化的类 for(Map.Entry<String, Object> entry: beans.entrySet()){ Object instace = entry.getValue(); Class<?> clazz = instace.getClass(); if(clazz.isAnnotationPresent(AaronController.class)){ Field[] fields =clazz.getDeclaredFields(); for(Field field : fields){ if(field.isAnnotationPresent(AaronAutowrited.class)){//判断当前遍历是否有注解 AaronAutowrited aaronAutowrited = field.getAnnotation(AaronAutowrited.class); String key = aaronAutowrited.value();//获取到 注解的value field.setAccessible(true);//因为是private 无法修改值 try { field.set(instace, beans.get(key)); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } }else{ continue; } } }else{ continue; } } } private void buildUrlMapping(){ if(beans.entrySet().size()<=0){//没有类的实例化 System.err.println("没有类的实例化"); return; } for(Map.Entry<String, Object> entry : beans.entrySet()){ Object instance = entry.getValue(); Class<?> clazz = instance.getClass(); if(clazz.isAnnotationPresent(AaronController.class)){ AaronRequestMapping aaronRequestMapping = clazz.getAnnotation(AaronRequestMapping.class); String classPath = aaronRequestMapping.value();//拿到类上的mapping Method[] methods = clazz.getMethods();//拿到类的方法 for(Method method : methods){ if(method.isAnnotationPresent(AaronRequestMapping.class)){//判断了方法上面是否有注解 AaronRequestMapping methodMapping = method.getAnnotation(AaronRequestMapping.class); String methodPath = methodMapping.value();//获取到注解的value handlerMap.put(classPath+methodPath, method); }else{ continue; } } }else{ continue; } } } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // TODO Auto-generated method stub System.err.println("test1"); this.doPost(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // TODO Auto-generated method stub //获取请求路径 /项目名/ctrl/method String uri = req.getRequestURI(); String content = req.getContextPath();//获取项目名 String path = uri.replace(content, "");//ctrl/method Method method = (Method)handlerMap.get(path); Object instance = (Object)beans.get("/"+path.split("/")[1]);// ctrl Object[] agrs = hand(req,resp,method); try { method.invoke(instance, agrs); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InvocationTargetException e) { // TODO Auto-generated catch block e.printStackTrace(); } super.doPost(req, resp); } //处理参数 private static Object[] hand(HttpServletRequest req, HttpServletResponse resp,Method method){ //拿到当前执行的方法有哪些参数 Class<?>[] paramClazzs = method.getParameterTypes(); //根据参数的个数 new一个存放参数的数组 Object[] args = new Object[paramClazzs.length]; int arg_i = 0 ; int index = 0; for(Class<?> paramClazz : paramClazzs){ if(ServletRequest.class.isAssignableFrom(paramClazz)){ args[arg_i++] = req; } if(ServletResponse.class.isAssignableFrom(paramClazz)){ args[arg_i++] = resp; } Annotation[] paramAns = method.getParameterAnnotations()[index]; if(paramAns.length>0){ for(Annotation paramAn : paramAns){ if(AaronRequestParam.class.isAssignableFrom(paramAn.getClass())){ AaronRequestParam rp = (AaronRequestParam)paramAn; args[arg_i++] = req.getParameter(rp.value()); } } } index++; } return args; } }
3、实战篇
controller代码
package org.aaron.mvc.ctrl; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.aaron.mvc.annaotation.AaronAutowrited; import org.aaron.mvc.annaotation.AaronController; import org.aaron.mvc.annaotation.AaronRequestMapping; import org.aaron.mvc.annaotation.AaronRequestParam; import org.aaron.mvc.service.TestService; @AaronController @AaronRequestMapping("/Aaron") public class TestCtrl { @AaronAutowrited("TestServiceImpl") private TestService service; @AaronRequestMapping("/query") public void query(HttpServletRequest request,HttpServletResponse response, @AaronRequestParam("name") String name, @AaronRequestParam("age") String age){ String result = service.query(name, age); try { PrintWriter out; response.setCharacterEncoding("utf-8"); response.setContentType("text/html; charset=utf-8"); out = response.getWriter(); out.write(result); out.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
service接口
package org.aaron.mvc.service; public interface TestService { String query(String name,String age); }
service接口实现
package org.aaron.mvc.service.impl; import org.aaron.mvc.annaotation.AaronService; import org.aaron.mvc.service.TestService; @AaronService("TestServiceImpl") public class TestServiceImpl implements TestService{ public String query(String name, String age) { // TODO Auto-generated method stub return "当前用户:"+name+"年龄"+age ; } }
作者:诗和远方
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.