spring---简易版

springmvc

一个dispatchservlet分发到对应的类里面的方法;

对应的类里面的方法,由一个集合映射;

spring

IOC,控制反转,由class反射实例化

 

实际操作:

第一步,创建个maven的web项目;

第二步,dispatchservlet的创建

由这一步产生的其他步骤

   1、创建等下要用到的标签

   这里就搞两个。一个controller,一个RequestMapping

@java.lang.annotation.Target(value = { java.lang.annotation.ElementType.TYPE })
@java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
@java.lang.annotation.Documented
public @interface Controller {
    String value() default "";
}

@java.lang.annotation.Target(value = { java.lang.annotation.ElementType.TYPE,java.lang.annotation.ElementType.METHOD })
@java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
@java.lang.annotation.Documented
public @interface RequestMapping {
    String value() default "";
}

   2、配置到web.xml

    <servlet>
    <description></description>
    <display-name>DispatchServlet</display-name>
    <servlet-name>DispatchServlet</servlet-name>
    <servlet-class>DispatchServlet</servlet-class>
    <init-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>application.properties</param-value>
    </init-param>
    <load-on-start>1</load-on-start>
  </servlet>
  <servlet-mapping>
    <servlet-name>DispatchServlet</servlet-name>
    <url-pattern>/*</url-pattern>
  </servlet-mapping>

2、编写DispatchServlet类继承javax.servlet.http.httpservlet

这里面涉及几个重要变量。全部围着它们转;

    web.xml里面servlet对应的配置属性<init-param>;location对应的就是param的name;来获取对应的文件的路径真实值

    private static final String LOCATION = "contextConfigLocation";    

    采用properties工具类把配置的文件加载放进properties实例里面;
    private java.util.Properties properties = new java.util.Properties();

    通过scan标签把每一个类对应的类名都存到集合里面
    private java.util.ArrayList<String> classNameArrayList = new java.util.ArrayList<String>();

    通过楼上把每个类对应的class,反射实例化的对象存起来,也是一个集合

    private java.util.HashMap<String, java.lang.Object> beanHashMap = new java.util.HashMap<String,java.lang.Object>();
    每个方法对应的映射存到一个集合。也是通过标签

    private java.util.HashMap<String, java.lang.reflect.Method> urlToMethodHashMap = new java.util.HashMap<String,java.lang.reflect.Method>();

    先初始化一切准备动作;

    楼上的全部变量都得初始化;

     四步,

     加载配置内容用到第一第二变量;

     递归遍历指定包目录下的所有文件,把所有的类名放到集合里;

     遍历楼上类名称集合,根据名称class.forname实例化全部对象;

     遍历楼上实例对象集合,把每个类实例,先是否继承controller,收集对应mapping的value值。同理实例对应全部method遍历,也是收集对应的mapping的value值。在存入集合。这就是url到method的集合。

    public void init(javax.servlet.ServletConfig servletConfig) {
        doLoadConfig(servletConfig.getInitParameter(LOCATION));
        doScanPackage(properties.getProperty("scanPackage"));
        doInstance();
        initHandlerMapping();
    }

public void doLoadConfig(String location) {
        java.io.InputStream inputStream = null;
        inputStream = this.getClass().getClassLoader().getResourceAsStream(location);
        try {
            properties.load(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }  
    public void doScanPackage(String packageName) {
        java.net.URL url = this.getClass().getClassLoader().getResource("/"+packageName.replaceAll("\\.", "/"));
        java.io.File files = new java.io.File(url.getFile());
        for(java.io.File file : files.listFiles()) {
            if(file.isDirectory()) {
                this.doScanPackage(packageName+"."+file.getName());
            }else {
                classNameArrayList.add((packageName+"."+file.getName()).replace(".class", "").trim());
            }
        }
    }  
    private void doInstance() {
        if(this.classNameArrayList.size()==0)return;
        try {
            for(java.lang.String className :this.classNameArrayList) {
                java.lang.Class<?> target = java.lang.Class.forName(className);
                if(target.isAnnotationPresent(Controller.class)) {
                    this.beanHashMap.put(target.getName().toLowerCase(), target.newInstance());
                }
            }            
        }catch(java.lang.ClassNotFoundException classNotFoundException) {
            classNotFoundException.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }
    public void initHandlerMapping() {
        if(this.beanHashMap.isEmpty()) return;
        java.util.Iterator<java.util.Map.Entry<String,java.lang.Object>> iterator = this.beanHashMap.entrySet().iterator();
        while(iterator.hasNext()) {
            java.util.Map.Entry<java.lang.String, java.lang.Object> entry = iterator.next();
            java.lang.Object object = entry.getValue();
            Class<?> target = object.getClass();
            if(!target.isAnnotationPresent(Controller.class)) {
                continue;
            }
            String objectUrlValue = "";
            if(target.isAnnotationPresent(RequestMapping.class)) {
                RequestMapping requestMapping = target.getAnnotation(RequestMapping.class);
                objectUrlValue = requestMapping.value();
            }
            for(java.lang.reflect.Method method : target.getMethods()) {
                if(!method.isAnnotationPresent(RequestMapping.class)) continue;
                RequestMapping requestMapping = method.getAnnotation(RequestMapping.class);
                String methodUrlValue = requestMapping.value();
                String url =  objectUrlValue + methodUrlValue;
                urlToMethodHashMap.put(url, method);
            }
        }
    }

到这里准备的初始化的代码都敲好了。

就差,来一个请求,怎么处理,分发到对应的类实例里面的方法

第三步:写分发的代码,

获取对应的类和方法的url

根据url在楼上的urltomethod的集合里面查询出对应的bean

把request的对应的parametermap全部一一匹配到对应method的对应变量。也就是依据变量名称。url里面变量也是=区分的

反射method调用。把对应的实例的class和对应参数给它。那就通了。

private void doDispatch(javax.servlet.http.HttpServletRequest request,javax.servlet.http.HttpServletResponse response) {
        if(this.urlToMethodHashMap.isEmpty()) return;
        String requestUri = request.getRequestURI();
        String contextPath = request.getContextPath();
        requestUri = requestUri.replace(contextPath, "").replaceAll("/+", "/");
        if(!this.urlToMethodHashMap.containsKey(requestUri)) {
            try {
                response.getWriter().println("not founded");
            } catch (IOException e) {
                e.printStackTrace();
            }
            return;
        }
        java.util.Map<String, String[]> objectParameterMap = request.getParameterMap();
        java.lang.reflect.Method method = this.urlToMethodHashMap.get(requestUri);
        java.lang.Class<?>[] methodParameterTypes = method.getParameterTypes();
        java.lang.Object[] objectsValue = new Object[methodParameterTypes.length];
        for(int i=0;i<methodParameterTypes.length;i++) {
            java.lang.Class<?> methodParameterClass = methodParameterTypes[i];
            if(methodParameterClass == javax.servlet.http.HttpServletRequest.class) {
                objectsValue[i] = request;
            }
            if(methodParameterClass == javax.servlet.http.HttpServletResponse.class) {
                objectsValue[i] = response;
            }
            if(methodParameterClass == String.class) {
                for(java.util.Map.Entry<String, String[]> temp : objectParameterMap.entrySet()) {
                    if(methodParameterClass.getName()==temp.getKey()) {
                        objectsValue[i] = temp.getValue();
                    }
                }
            }
        }
        try {
            method.invoke(this.beanHashMap.get(method.getDeclaringClass().getName().toLowerCase()), objectsValue);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doDispatch(request,response);
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值