抄写原生项目_day02

安稳与你 提交于 2020-03-23 12:20:39

3 月,跳不动了?>>>

非常粗糙的模仿spring扫描注解,先定义三个注解

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Controller {
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface RequestMapping {
    String value();
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Service {
}

在监听中进行扫描并加入到context容器之中

public void contextInitialized(ServletContextEvent servletContextEvent) {
    //获取容器配置并初始化
    ServletContext servletContext = servletContextEvent.getServletContext();
    String initParameter = servletContext.getInitParameter("context");
    Context.setContextPath(initParameter);
    //首次加载context
    Context context = Context.getContext();
    //加载所有controller
    AnnotationScanner.getAnnotationScanner().scan(Controller.class);
    //加载所有service
    AnnotationScanner.getAnnotationScanner().scan(Service.class);
    //加载所有配置扫描的bean
    AnnotationScanner.getAnnotationScanner().beanConfigScan();
    //扫描requestmapping方法
    AnnotationScanner.getAnnotationScanner().scan(RequestMapping.class);
}

扫描类


public class AnnotationScanner {

    private final String CONTROLLER_SCAN="controller-scan";
    private final String SERVICE_SCAN="service-scan";
    private final String BEAN_SCAN="bean-scan";

    private static AnnotationScanner annotationScanner = new AnnotationScanner();
    private AnnotationScanner(){}
    public static AnnotationScanner getAnnotationScanner(){
        return annotationScanner;
    }
    public  List scanByAnnotation(String path,Class anonotation){
        List annotationClazz = new LinkedList<Class>();
        try {
            URL resource = AnnotationScanner.class.getClassLoader().getResource(path.replaceAll("\\.", "/"));
            File file = new File(resource.toURI());
            File[] files = file.listFiles(new FileFilter() {
                @Override
                public boolean accept(File f) {
                    if(f.isDirectory()){
                        scanByAnnotation(path,anonotation);
                    }else{
                        try {
                            String classPath = path + "." + f.getName().replaceAll("\\.class", "");
                            Class<?> aClass = AnnotationScanner.class.getClassLoader().loadClass(classPath);
                            if (aClass.isAnnotationPresent(anonotation)){
                                annotationClazz.add(aClass);
                            }
                        }catch (Exception e){
                            e.printStackTrace();
                        }
                    }
                    return false;
                }
            });
        }catch (Exception e){
            e.printStackTrace();
        }
        return annotationClazz ;
    }

    public  List scanByBasePackage(String path){
        List annotationClazz = new LinkedList<Class>();
        try {
            URL resource = AnnotationScanner.class.getClassLoader().getResource(path.replaceAll("\\.", "/"));
            File file = new File(resource.toURI());
            File[] files = file.listFiles(new FileFilter() {
                @Override
                public boolean accept(File f) {
                    if(f.isDirectory()){
                        scanByBasePackage(path);
                    }else{
                        try {
                            String classPath = path + "." + f.getName().replaceAll("\\.class", "");
                            Class<?> aClass = AnnotationScanner.class.getClassLoader().loadClass(classPath);
                                annotationClazz.add(aClass);
                        }catch (Exception e){
                            e.printStackTrace();
                        }
                    }
                    return false;
                }
            });
        }catch (Exception e){
            e.printStackTrace();
        }
        return annotationClazz ;
    }


    public Map getBeansMap(List<Class> list){
        Map map = new HashMap<String ,Object >();
        list.forEach(l->{
            try {
                Object o = l.newInstance();
                map.put(l.getName(),o);
            } catch (Exception e) {
                e.printStackTrace();
            }

        });
        return map ;
    }
    //根据class进行扫描
    public void scan(Class clazz){
        Context context = Context.getContext();
        if(clazz.getName().equalsIgnoreCase(Controller.class.getName())){
            List list = AnnotationScanner.getAnnotationScanner().scanByAnnotation((String) context.getElement(CONTROLLER_SCAN), Controller.class);
            context.addElement("controller",AnnotationScanner.getAnnotationScanner().getBeansMap(list));
        }
        if(clazz.getName().equalsIgnoreCase(Service.class.getName())){
            List list = AnnotationScanner.getAnnotationScanner().scanByAnnotation((String) context.getElement(SERVICE_SCAN), Service.class);
            context.addElement("service",AnnotationScanner.getAnnotationScanner().getBeansMap(list));
        }
        if (clazz.getName().equalsIgnoreCase(RequestMapping.class.getName())){
            scanRequestMapping();
        }
    }
    public void scan(String basePath ){
        Context context = Context.getContext();
        List list = AnnotationScanner.getAnnotationScanner().scanByBasePackage(basePath);
        Map beansMap = getBeansMap(list);
        context.addElement("bean",beansMap);
    }
    //扫描bean
    public void beanConfigScan(  ){
        String  basePath  = (String) Context.getContext().getElement(BEAN_SCAN);
        scan(basePath);
    }

    //扫描所有被RequestMapping注解的方法,并且加入到Context容器里面(默认必须标记在Controller类下)
    public void scanRequestMapping(){
        Map  map  = (Map)Context.getContext().getElement("controller");
        System.out.println(map);
        Map requestmapping = new HashMap<String ,Object >();
        map.forEach((k,v)->{
            //获取类下的所有方法
            Method[] declaredMethods = v.getClass().getDeclaredMethods();
            //获取类上的注解并且遍历RequestMapping注解,有的话,加入到map里面
            for(Method method:declaredMethods){
                if (method.isAnnotationPresent(RequestMapping.class)){
                    RequestMapping annotation = method.getAnnotation(RequestMapping.class);
                    //ReuqestMapping上注解的路径
                    String value = annotation.value();
                    ReflectBean reflectBean = new ReflectBean(value, v, method);
                    //加入到mapping map                     requestmapping.put(value,reflectBean);
                }
            }
         //把扫描到的注解方法加入到context         Context.getContext().addElement("requestmapping",requestmapping);
        });
    }

}

测试效果,项目要做登录,先定义一个登录接口进行测试

@Controller
public class GlobalController {
    //实现自动注入 need to do
    @RequestMapping("login")
    public Object login(HttpServletRequest request , HttpServletResponse response){
        String name = request.getParameter("name");
        return GlobalResponse.ok(new HashMap<>(),"登录成功");
    }
}

这个是web.xml下配置的唯一一个servlet,反射调用requestmapping中对应path的方法

public class DispatcherServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doRequest(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doRequest(req, resp);
    }

    protected  void doRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
        Context context = Context.getContext();
        Map requestmapping = (Map)context.getElement("requestmapping");
        System.out.println(requestmapping);
        //找到对应的requestmapping
        String action = request.getParameter("action");
        if(MyUtils.haskey(action,requestmapping)){
            ReflectBean reflectBean = (ReflectBean) requestmapping.get(action);
            try {
                Object invoke = reflectBean.getMethod().invoke(reflectBean.getObject(), request, response);

                writeAndClose(response,JsonUtils.getJson(invoke));
            }catch (Exception e){
                e.printStackTrace();
            }
        }else{
            writeAndClose(response, JsonUtils.getJson(GlobalResponse.nok("拒绝访问")));
        }
    }
    private void writeAndClose(HttpServletResponse response , String json) throws IOException {
        PrintWriter writer = response.getWriter();
        writer.write(json);
        writer.close();
    }
}

ajax访问测试

        var urll = "http://10.10.12.150:8080/door_war/action";
        $.ajax({
            type:"post",
            //xhrFields:{withCredentials:true},
            url:urll,
            data:{
                action:"login",
                name:'test',
                password:'a123456'
            },
            success:function(res){
                console.log(res)
            }
        });

前端返回

{issuccess: true, message: "登录成功", exception: null, data: {…}, recordcount: 0}
基本上算是成功了

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!