1、加載帶有@Controller註解的控制器java
1.一、首先咱們須要獲取帶有@Controller註解的全部類,所以能夠經過咱們事先寫好的ClassHelper.java來獲取。apache
1.二、獲取到全部帶有@Controller註解的Class對象後,進而能夠經過反射來獲取帶有@Action註解的方法,獲取@Action的值(也就是請求表達式),進而獲取請求方法和請求路徑。數組
1.三、因此咱們須要把請求方法和請求路徑封裝到一個Request對象中。app
package org.smart4j.framework.bean; import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; public class Request { /** * 請求方法 */ private String requestMethod; /** * 請求路徑 */ private String requestPath; public Request() { } public Request(String requestMethod, String requestPath) { this.requestMethod = requestMethod; this.requestPath = requestPath; } public String getRequestMethod() { return requestMethod; } public String getRequestPath() { return requestPath; } //TODO @Override public int hashCode() { return HashCodeBuilder.reflectionHashCode(this); } @Override public boolean equals(Object obj) { return EqualsBuilder.reflectionEquals(this,obj); } }
1.四、如何根據Request對象的屬性找到須要調用的方法呢?這時候咱們須要編寫一個處理對象Handler類。來封裝須要調用的Class對象的方法。框架
package org.smart4j.framework.bean; import java.lang.reflect.Method; /** * 封裝Action信息 * @author Admin * */ public class Handler { /** * controller類 */ private Class<?> controllerClass; /** * method方法 */ private Method actionMethod; public Handler() { } public Handler(Class<?> controllerClass, Method actionMethod) { this.controllerClass = controllerClass; this.actionMethod = actionMethod; } public Class<?> getControllerClass() { return controllerClass; } public Method getActionMethod() { return actionMethod; } }
1.五、咱們能夠把Request和Handler進行一個關聯映射。放入一個Map中。當客戶端一個請求(HttpServletRequest)過來的時候,獲取請求的url和ActionMap裏的key( Request對象 )作比較,若是相等的話, 就找到ActionMap的key對應的value(也就是Handler處理器)來調用相應的方法。ide
1.六、最後,咱們創建一個ControllerHelper.java類實現一個Map映射來初始化咱們封裝好的Request對象和Handler對象,保存處理器和映射關係。ui
package org.smart4j.framework.helper; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; import java.util.Set; import org.apache.commons.collections4.CollectionUtils; import org.smart4j.framework.annotation.Action; import org.smart4j.framework.annotation.Service; import org.smart4j.framework.bean.Handler; import org.smart4j.framework.bean.Request; import org.smart4j.framework.util.ArrayUtil; /** * 控制器助手類 * @author Admin * */ public final class ControllerHelper { /** *用於存放請求和處理器的映射關係 */ private static final Map<Request,Handler> ACTION_MAP = new HashMap<Request,Handler>(); //初始化映射關係 static{ //獲取全部@Controller註解下的全部Java類的Class對象 Set<Class<?>> controllerClassSet = ClassHelper.getClassController(); if( CollectionUtils.isNotEmpty( controllerClassSet ) ){ for (Class<?> controllerClass : controllerClassSet) { //遍歷Controller類 Method[] methods = controllerClass.getDeclaredMethods(); //獲取單個Class對象下的全部Method對象。 if( ArrayUtil.isNotEmpty(methods) ){ //若是methods數組不爲空 for (Method method : methods) { //遍歷全部的method //判斷當前方法是否包含Action註解 if( method.isAnnotationPresent( Action.class ) ){ Action action = method.getAnnotation( Action.class ); //從Action中獲取url映射規則 String mapping = action.value(); //獲取當前方法的@Action value的url地址和方法 //驗證URL映射規則 if( mapping.matches("\\w+:/\\w*") ){ //regex String[] array = mapping.split(":"); //拆分 if( ArrayUtil.isNotEmpty(array) && array.length == 2 ) { //獲取請求路徑和請求方法 String requestMethod = array[0]; String requestPath = array[1]; //封裝到Request對象中 Request request = new Request(requestMethod, requestPath); //封裝Handler對象 Handler handler = new Handler(controllerClass, method); ACTION_MAP.put( request , handler ); } } } } } } } } /** * TODO * 獲取Handler * @param requestMethod * @param requestPath * @return */ public static Handler getHandler(String requestMethod,String requestPath){ Request request = new Request(requestMethod, requestPath); return ACTION_MAP.get(request); } }
---------------------------------------summarize(總結):基於@Action註解的Request和Handler對象已經映射完畢了。解析來就能夠初始化框架了---------------------------------------this