Annotation
JDK5之后,增加了Annotation注解的基本语法,通过注解可以省略XML的配置信息,简化代码的编写形式。
Annotation中,自定义语法如下:
@Target(ElementType.xxx) @Retention(RetentionPolicy.xxx) public @interface 注解名{ }
Target:对应的是当前的注解能够定义在哪个位置上
ElementType.Type--类
ElementType.Field--字段
ElementType.Method--方法
Retention:在什么场景下能够起作用
RetentionPolicy.CLASS--定义类
RetentionPolicy.RUNTIME--运行时
根据自定义MVC框架的一个需求,定义两个Annotation:
@Controller
@Target(Element.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface Controller{ }
@RequestMapping
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface RequestMapping{ String value() default "" ; }
解析Annotation
将所有包含了@Controller类进行遍历
/** * 找到某个包下的所有的以.class结尾的java文件 */ public class ClassScanner { /** * 获得包下面的所有的class * @param * @return List包含所有class的实例 */ public static List<Class<?>> getClasssFromPackage(String packageName){ List<Class<?>> clazzs = new ArrayList<>(); // 是否循环搜索子包 boolean recursive = true; // 包名对应的路径名称 String packageDirName =packageName.replace('.','/'); Enumeration<URL> dirs; try { //从当前正在运行的线程中,加载类加载器,通过给定的包名,找到所有该包下的类 dirs= Thread.currentThread().getContextClassLoader().getResources(packageDirName); while(dirs.hasMoreElements()) { URL url =dirs.nextElement(); String protocol =url.getProtocol(); if("file".equals(protocol)) { String filePath =URLDecoder.decode(url.getFile(), "UTF-8"); findClassInPackageByFile(packageName,filePath, recursive, clazzs); } } } catch (Exception e) { e.printstacktrace(); } return clazzs; } /** * 在package对应的路径下找到所有的class */ public static void findClassInPackageByFile(String packageName, String filePath,final boolean recursive,List<Class<?>> clazzs) { File dir = new File(filePath); if (!dir.exists() ||!dir.isDirectory()) { return; } // 在给定的目录下找到所有的文件,并且进行条件过滤 File[] dirFiles =dir.listFiles(new FileFilter() { public boolean accept(File file) { boolean acceptDir =recursive && file.isDirectory();// 接受dir目录 boolean acceptClass =file.getName().endsWith("class");// 接受class文件 return acceptDir ||acceptClass; } }); for (File file : dirFiles) { if (file.isDirectory()) { findClassInPackageByFile(packageName +"." + file.getName(),file.getAbsolutePath(), recursive,clazzs); } else { String className =file.getName().substring(0,file.getName().length() - 6); try { clazzs.add(Thread.currentThread().getContextClassLoader().loadClass(packageName+ "." + className)); } catch (Exception e) { e.printstacktrace(); } } } } }
ClassLoaderController
public class ClassLoaderContextListener implements servletcontextlistener { @Override public void contextinitialized(ServletContextEventsce) { initClassLoader() ; } private void initClassLoader() { //根据包找到包下面所有的类 List<Class<?>> classList =ClassScanner.getClasssFromPackage("com.csi.controller"); for (Class clazz : classList) { //如果当前类上存在Controller,就要获取方法 if(clazz.isAnnotationPresent(Controller.class)) { Method[] methods =clazz.getmethods(); //遍历当前包含了Controller注解的所有方法 for (Method method :methods) { //判断方法上是否添加了RequestMapping注解 if(method.isAnnotationPresent(RequestMapping.class)) { //获取到包含了RequestMapping注解的value值 String urlPath =method.getAnnotation(RequestMapping.class).value(); //将值作为键,将方法作为值,存储在map集合中 WebApplicationContext.methodMap.put(urlPath,method) ; } } } } } }
解析用户请求的路径
public class dispatcherServlet extends HttpServlet { @Override protected void service(HttpServletRequest req,HttpServletResponse resp) throws servletexception, IOException { //步骤1:获取到用户的请求URL String urlPath =req.getServletPath() ; Method method =WebApplicationContext.methodMap.get(urlPath); if(method != null) { //步骤2:调用对应的Method方法 Object instance = null; try { //2-1:如何找到要对应的类 instance =method.getDeclaringClass().newInstance(); } catch(InstantiationException e) { e.printstacktrace(); } catch(illegalaccessexception e) { e.printstacktrace(); } //2-2:如何传输参数,request,response try { method.invoke(instance,req,resp) ; } catch(illegalaccessexception e) { e.printstacktrace(); } catch(InvocationTargetException e) { e.printstacktrace(); } }else{ resp.sendRedirect("failure.jsp"); } } }
使用
需要在项目里建立com.csi.controller包
在包中创建类,在类上一行添加@Controller注解
建立类的方法,根据需求,在适当的方法上添加@RequestMapping注解
在@RequestMapping注解中添加url请求的路径
@Controller public class ProdectController{ @RequestMapping("/show.do") public void to_show_page(HttpServletRequest request, HttpServletResponse response) throws servletexception,IOException { request.setAttribute("hello","world"); request.getRequestdispatcher("/show.jsp").forward(request,response); }
原文地址:https://www.jb51.cc/wenti/3286358.html
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。