目录结构:
上代码
Controller.java
package com.alan.mvc.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME)//运行时还存在 public @interface Controller { public String value() default ""; } DispatcherServlet.java package com.alan.mvc.annotation; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.alan.mvc.util.ScannerUtil; //核心控制器 @WebServlet(urlPatterns={"*.do"},loadOnStartup = 0) public class DispatcherServlet extends HttpServlet { private static final long serialVersionUID = 1L; private final static String BASEPACKAGE="com.alan.controller"; private Map<String, Object> coltrollers = new HashMap<>(); private Map<String, Method> methods = new HashMap<>(); @Override public void init() throws ServletException { System.out.println("开始扫描:"+BASEPACKAGE); Map<String, Class<?>> scannerClass = ScannerUtil.scannerClass(BASEPACKAGE); Iterator<String> iterator = scannerClass.keySet().iterator(); while (iterator.hasNext()) { String className = (String) iterator.next(); Class<?> c= scannerClass.get(className); //判断当前类是否有controller注解 if (c.isAnnotationPresent(Controller.class)) { String path=""; if (c.isAnnotationPresent(RequestMapping.class)) { path=((RequestMapping)c.getAnnotation(RequestMapping.class)).value(); } try { coltrollers.put(className, c.newInstance()); Method[] ms = c.getMethods(); for (Method method : ms) { if (method.isAnnotationPresent(RequestMapping.class)) { methods.put(path += ((RequestMapping)method.getAnnotation(RequestMapping.class)).value(),method); } } } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } } System.out.println("扫描结束,size:"+scannerClass.size()); } @Override public void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String contextPath = req.getContextPath(); String requestURI = req.getRequestURI(); if (requestURI.equals(contextPath+"/")) { requestURI=requestURI+"index.do"; } String mappingPath = requestURI.substring(requestURI.indexOf(contextPath)+contextPath.length(), requestURI.indexOf(".do")); Method method = methods.get(mappingPath); try { method.invoke(coltrollers.get(method.getDeclaringClass().getName())); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } } RequestMapping.java package com.alan.mvc.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target({ElementType.TYPE,ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME)//运行时还存在 public @interface RequestMapping { public String value(); }ScannerUtil.java
package com.alan.mvc.util; import java.io.File; import java.io.UnsupportedEncodingException; import java.net.URL; import java.net.URLDecoder; import java.util.HashMap; import java.util.Map; //扫描工具类--将制定的类加载进内存 public class ScannerUtil { //扫描包 public static void main(String[] args) { //配置文件中配置包名 scannerClass("com.alan.controller"); } public static Map<String,Class<?>> scannerClass(String packagePath){ // String filePath = packagePath.replace(".", "/")+"/"; System.out.println(filePath); Map<String,Class<?>> classes = new HashMap<>(); //取得路径对象 URL url = Thread.currentThread().getContextClassLoader().getResource(filePath); System.out.println(url.getPath()); //判断文件是文件还是文件夹 if (url.getProtocol().equals("file")) { String path = url.getPath(); if (path.contains("")) { } File folder = null; try { folder = new File(URLDecoder.decode(url.getPath(),"utf-8").substring(1)); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } //扫描所有(子文件夹)类 scannerFile(folder,filePath,classes); } return classes; } private static void scannerFile(File folder, String root, Map<String, Class<?>> classes) { //先找到所在这个文件下下的文件对象 File[] listFiles = folder.listFiles(); for (File file : listFiles) { //是不是文件夹 if (file.isDirectory()) { scannerFile(file,root+file.getName()+"/",classes); }else { String path=file.getAbsolutePath(); //判断路径是不是以.class结尾 if (path.endsWith(".class")) { path = path.replace("\\", "/"); String className = root+path.substring(path.lastIndexOf("/")+1, path.indexOf(".class")); className=className.replace("/","."); System.out.println(className); try { classes.put(className, Class.forName(className)); } catch (ClassNotFoundException e) { e.printStackTrace(); } } } } } } 测试: package com.alan.controller; import com.alan.mvc.annotation.Controller; import com.alan.mvc.annotation.RequestMapping; @Controller @RequestMapping("/index") public class indexController { @RequestMapping("/doSomeThing") public void dosomething() { System.out.println("hello"); } }
