【从零写javaweb框架】(六)加载Controller

在上一篇我们实现了依赖注入功能【从零写javaweb框架】(五)实现依赖注入功能

现在编写一个ControllerHelper

通过ClassHelper,可以获取所有定义了Controller注解的类,然后再通过反射获取该类中所有带有Action注解的方法,获取Action注解中的请求表达式,进而获取请求方法与请求路径,封装一个请求对象(Request)与处理对象(Handler),最后将Request与Handler建立一个映射关系,放入一个Action Map中,并提供一个可根据请求方法与请求路径获取处理对象的方法。


以下步骤均在框架项目中进行

那么,根据上面所说,我们首先需要封装一个Request类,和Handler类。

Request类

package org.smart4j.framework.bean;

import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;

/**
 * desc : 请求信息的封装
 * Created by Lon on 2018/1/28.
 */
public class Request {

    /**
     * 请求方法(如GET和POST)
     */
    private String requestMethod;

    /**
     * 请求路径
     */
    private String requestPath;

    public Request(String requestMethod, String requestPath) {
        this.requestMethod = requestMethod;
        this.requestPath = requestPath;
    }

    public String getRequestMethod() {
        return requestMethod;
    }

    public String getRequestPath() {
        return requestPath;
    }

    /**
     * 这个方法之前没见过,查资料之后才知道:
     * reflectionHashCode是通过反射得到当前对象的各个属性,
     * 然后将它们作字符串拼接(append),最后再得到拼接后的字符串的哈希码
     */
    @Override
    public int hashCode() {
        return HashCodeBuilder.reflectionHashCode(this);
    }

    /**
     * reflectionEquals与reflectionHashCode相对应
     */
    @Override
    public boolean equals(Object obj) {
        return EqualsBuilder.reflectionEquals(this, obj);
    }

}


Handler类

package org.smart4j.framework.bean;

import java.lang.reflect.Method;

/**
 * desc : 封装Action信息
 * Created by Lon on 2018/1/28.
 */
public class Handler {

    /**
     * Controller类
     */
    private Class<?> controllerClass;

    /**
     * Action方法
     */
    private Method actionMethod;

    public Handler(Class<?> controllerClass, Method actionMethod) {
        this.controllerClass = controllerClass;
        this.actionMethod = actionMethod;
    }

    public Class<?> getControllerClass() {
        return controllerClass;
    }

    public Method getActionMethod() {
        return actionMethod;
    }
}


最后就是我们要写的ControllerHelper:

package org.smart4j.framework.helper;

import org.smart4j.framework.annotation.Action;
import org.smart4j.framework.bean.Handler;
import org.smart4j.framework.bean.Request;
import org.smart4j.framework.util.ArrayUtil;
import org.smart4j.framework.util.CollectionUtil;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * desc : 控制器助手类
 * Created by Lon on 2018/1/28.
 */
public final class ControllerHelper {

    /**
     * 用于存放请求与处理器之间的映射关系(Action Map)
     */
    private static final Map<Request, Handler> ACTION_MAP = new HashMap<Request, Handler>();

    static {
        //获取所有Controller类
        Set<Class<?>> controllerClassSet = ClassHelper.getControllerClassSet();
        if (CollectionUtil.isNotEmpty(controllerClassSet)){
            //遍历controllerClassSet
            for (Class<?> controllerClass : controllerClassSet){
                //获取Controller类中定义的方法
                Method[] methods = controllerClass.getDeclaredMethods();
                if (ArrayUtil.isNotEmpty(methods)){
                    //遍历这些Controller类中的方法
                    for (Method method : methods){
                        //判断当前方法是否带有Action注解
                        if (method.isAnnotationPresent(Action.class)){
                            //从Action注解中获取URL映射规划
                            Action action = method.getAnnotation(Action.class);
                            String mapping = action.value();
                            //验证URL映射规划
                            if (mapping.matches("\\w+:/\\w*")){
                                String[] array = mapping.split(":");
                                if (ArrayUtil.isNotEmpty(array) && array.length == 2){
                                    //获取请求方法与请求路径
                                    String requestMethod = array[0];
                                    String requestPath = array[1];
                                    Request request = new Request(requestMethod, requestPath);
                                    Handler handler = new Handler(controllerClass, method);
                                    //初始化Action Map
                                    ACTION_MAP.put(request, handler);
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    /**
     * 获取Handler
     */
    public static Handler getHandler(String requestMethod, String requestPath){
        Request request = new Request(requestMethod, requestPath);
        return ACTION_MAP.get(request);
    }

}


最后来一张框架目录:



总结:

这一篇里,我封装了Request和Handler,并写了ControllerHelper来维护维护Request与Handler之间的映射关系。

下一篇开始实现框架的初始化。




©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页