• 反射+注解的使用


    反射+注解的使用

    测试目录结构

    扫描工具

    package com.utils;
    
    import java.io.File;
    import java.net.URLDecoder;
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * 扫描工具类,用于扫描指定包下面的所有类,包括子包
     * @author xdzy
     */
    public class ScanUtil {
        /**
         * 存放所有类的类名
         */
        private static List<String> list = new ArrayList<String>();
    
        /**
         * 扫描
         * @param packagePath
         * @return
         */
        public static List<String> scanPackage(String packages) {
            String[] packs = packages.split(",");
            for (String pack : packs) {
                String path = toPackagePath(pack);
                try {
                    toClassPath(path);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            
            
            return list;
        }
    
        /**
         * 将路径转换成包名
         * @param packagePath
         * @return
         */
        private static String toPackagePath(String packagePath) {
            packagePath = packagePath.replace(".", File.separator);
            return getRealPath()+packagePath;
        }
    
        /**
         * 遍历目录将类名存入List中
         * @param classPath
         * @throws Exception
         */
        private static void toClassPath(String classPath) throws Exception {
            classPath = URLDecoder.decode(classPath, "utf-8");
            // listFiles()获取路径下的所有文件或文件夹,返回的是一个File[]数组
            File[] fs = new File(classPath).listFiles();
            if (fs != null) {
                for (File file : fs) {
                    // file.isDirectory()方法判断当前额的file对象是否是一个文件夹
                    if (file.isDirectory()) {
                        // 获取文件夹的绝度路径
                        // 递归调用
                        toClassPath(file.getAbsolutePath());
                    } else {
                        // 将文件名转换成完整类名
                        String path = toClassName(file);
                        if (path != null) {
                            list.add(path);
                        }
                    }
                }
            }
        }
    
        /**
         *  将文件名转换成完整类名
         * @param file
         * @return
         * @throws Exception
         */
        private static String toClassName(File file) throws Exception {
            if (file.getName().endsWith(".class")) {
                String path = URLDecoder.decode(getRealPath(), "utf-8");
                path = new File(path).getAbsolutePath() + File.separator;
                path = file.getAbsolutePath().substring(path.length(),
                        file.getAbsolutePath().length());
                String className = path.replace(File.separator, ".");
                className = className.substring(0, className.length() - 6);
                return className;
            } else {
                return null;
            }
        }
        
        /**
         * 获取当前项目的classes目录
         * @return
         */
        private static String getRealPath(){
            return ScanUtil.class.getClassLoader().getResource("").getPath();
        }
    
        public static void main(String[] args) throws Exception{                
            ScanUtil.scanPackage("org.evergreen.web");
            for (String string : list) {
                System.out.println(string);
            }
        }
    }

    自定义注解

    @Target(ElementType.METHOD)  
    @Retention(RetentionPolicy.RUNTIME)  
    public @interface UrlMapper {  
        String value() default "";  
    }  

    中央处理器(servlet)

    package com.servlet;
    
    import com.annotation.UrlMapper;
    import com.utils.ScanUtil;
    
    import javax.servlet.ServletConfig;
    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 java.io.IOException;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    /**
     * @author: xdzy
     * @date: 2018/8/31 15:44
     * @description: 根据请求url找到相应类里面的相应注解,然后执行相应方法
     */
    @WebServlet("/")
    public class DispatcherServlet extends HttpServlet {
        //String表示url;Method表示方法名
        private static final Map<String, Method> mapper=new HashMap<>();
    
        //扫描指定文件夹下的类
        private List<String> scan(String packageName){
            //返回指定文件夹下所有的类的路径
            return ScanUtil.scanPackage(packageName);
        }
    
        //根据扫描到的类获取该类里面的方法上面的注解
        private void resolve(List<String> classNames){
            //遍历所有的类路径
            for(String className:classNames){
                try{
                    //获取该类的Class对象
                    Class<?> clazz=Class.forName(className);
                    //获取该类的所有方法名
                    Method[] methods=clazz.getMethods();
                    //遍历所有的方法
                    for (Method method:methods){
                        //判断该方法上面是否有该注解
                        if(method.isAnnotationPresent(UrlMapper.class)){
                            //获取当前方法上注解的value值,也就是请求的url
                            String url=method.getDeclaredAnnotation(UrlMapper.class).value();
                            //放到集合中
                            mapper.put(url,method);
                        }
                    }
                }catch (ClassNotFoundException e){
                    throw new RuntimeException(e.getMessage());
                }
            }
        }
    
        //根据url调用具体方法
        private void invokeTargetMethod(HttpServletRequest request, HttpServletResponse response, Method method){
            try {
                //先获取定义该方法的类实例
                Object instance = method.getDeclaringClass().newInstance();
                //进行方法的回调
                method.invoke(instance, request, response);
            } catch (InstantiationException e) {
                throw new RuntimeException(e.getMessage());
            } catch (IllegalAccessException e) {
                throw new RuntimeException(e.getMessage());
            } catch (InvocationTargetException e) {
                throw new RuntimeException(e.getMessage());
            }
        }
    
        @Override
        public void init(ServletConfig config) throws ServletException {
            //1. 全局的扫描
            List<String> classNames = scan("");
            //2. 解析类并缓存类中带有注解的方法
            resolve(classNames);
            System.out.println("DispatcherServlet初始化完成...");
        }
    
        @Override
        protected void service(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            //获取请求的url,这个path其实就对应了mapper中的key
            String path = request.getServletPath();
            //根据key取出相应的method并调用处理请求
            invokeTargetMethod(request, response, mapper.get(path));
        }
    }

    测试类

    package com.servletTest;
    
    import com.annotation.UrlMapper;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    /**
     * @author: xdzy
     * @date: 2018/9/1 11:41
     * @description: 用户所有操作
     */
    public class UserController {
        @UrlMapper("/login")
        public void login(HttpServletRequest request, HttpServletResponse response){
            System.out.println("login...");
            String name = request.getParameter("userName");
            System.out.println(name);
        }
    
        @UrlMapper("/addUser")
        public void addUser(HttpServletRequest request, HttpServletResponse response){
            System.out.println("addUser...");
            String name = request.getParameter("userName");
            System.out.println(name);
        }
    }
  • 相关阅读:
    美化单选按钮
    url的处理
    时间戳处理
    模板渲染引擎手册
    Web前端工具——Live Reload – Chrome扩展
    属性(Properties)和字段在C#中的关系
    MVC3中的Model
    使用System.Web.Mvc.Ajax
    javascript之DOM操作
    Javascript之BOM(window对象)
  • 原文地址:https://www.cnblogs.com/xdzy/p/9584228.html
Copyright © 2020-2023  润新知