dreamvc框架(三),dispartcher做了些什么
这一篇我会介绍一些dreamvc的核心类Dispatcher都做了些什么,首先我们先来看一看init方法,这是在DispatcherServlet和DispatcherFilter里面都会调用到的一个方法
void init(FixableConfig config)throws ServletException{ this.servletContext=config.getServletContext(); try { initProxy(config); log.info("init controllers and control"); } catch (ServletException e) { throw e; } catch (Exception e) { throw new ServletException("Dispatcher init failed.", e); } }
/** * controller/Interceptor/ * @param config context * @throws Exception */ private void initProxy(FixableConfig config)throws Exception { String IocName=config.getInitParameter("container"); if(IocName==null||"".equals(IocName)){ throw new NoParamterException("Missing init parameter <container>."); } /* CodeEnhancement=config.getInitParameter("CodeEnhancement"); if(CodeEnhancement==null||CodeEnhancement.equals("")){ throw new NoParamterException("Missing init parameter <CodeEnhancement>."); } if(!CodeEnhancement.equals("SpringAsm")&!CodeEnhancement.equals("javassist")){ throw new NoParamterException("You must get a right codeEnhancement handler like SpringAsm if your IOC is Spring"); }*/ IocFactory factory=FactoryHelper.getInstance().createIocFactory(IocName); factory.init(servletContext); List<Object> controllerBean=factory.getControllers(); List<Object> InterceptorBeans=factory.getInterceptors(); //controller/interceptor initControllerHander(controllerBean); initInterceptorHander(InterceptorBeans); initTemplates(config); }在initProxy这个方法中,首先我们先得到ioc模块,初始化后,一次得到controller和interceptor集合,接着进行操作和模板的初始化,先来看initControllerHander
private void initControllerHander(List<Object> controllerBean) { log.info("handler controller init"); int size=controllerBean.size(); for (int i = 0; i < size; i++) { Object obj=controllerBean.get(i); addUrlMather(obj); } }
private void addUrlMather(Object obj) { Class clazz=obj.getClass(); Method[] method=clazz.getMethods(); for (int i = 0; i < method.length; i++) { if(isLegalMethod(method[i])){ String annotation=method[i].getAnnotation(RequestURI.class).value(); Action action=new Action(obj, method[i]); URI uri=new URI(annotation); uri_action.put(uri, action); } } }
/** * * @param method * @return */ private boolean isLegalMethod(Method method) { RequestURI requestURI=method.getAnnotation(RequestURI.class); if(requestURI==null||requestURI.value().length()==0){ return false; } if(Modifier.isStatic(method.getModifiers())){ return false; } Class<?>[] putParameters=method.getParameterTypes(); for (Class<?> class1 : putParameters) { if(!switcherFactory.isLegalMethod(class1)){ return false; } } Class<?> retType = method.getReturnType(); if (retType.equals(void.class) || retType.equals(String.class) || Renderer.class.isAssignableFrom(retType) ){ return true; }else{ log.warn("Your method named "+method.getName()+"'s result type must be String/void/Templement"); } return false; }我们首先要得到这个controller里面的对应方法,然后对该方法进行检查,关键字,返回值,参数等等,Switcher包里面里面定义了一些对参数的处理,主要是对参数的检查等,读者可以自行查看,然后我们会得到annotation注解,也就是该方法的请求路径,关联到URI这个类里面,
package org.majorxie.dreamvc.tag; import java.util.ArrayList; import java.util.List; import java.util.Map; import org.majorxie.dreamvc.interceptor.Interceptor; /** * uri 类 * @author xiezhaodong * */ public class URI { private String uri; public String getUri() { return uri; } public void setUri(String uri) { this.uri = uri; } public URI(String uri) { super(); this.uri = uri; } /** * 匹配相应的interceptor * @param interceptor_map 装有interceptor的map * @return 该请求路径的拦截器链 */ public List<Interceptor> getMatchedInterceptor(Map<String,Interceptor> interceptor_map){ List<Interceptor> list=new ArrayList<Interceptor>(); for (String interceptorUri:interceptor_map.keySet()) { String returnInterceptor=matcher(this.uri, interceptorUri); if(returnInterceptor!=null){ list.add(interceptor_map.get(returnInterceptor)); } } return list; } /** * 判断url和拦截器路径是否相对等价比如 /user/login和/user/*是相对等价的,就能够匹配 * @param url 请求url * @param interceptors 拦截器url * @return 匹配成功返回,否则返回null */ public String matcher(String url,String interceptors){ if(url.equals(interceptors))return interceptors;//完全相同 if(interceptors.endsWith("/"))return null;//不能这样结尾 String[] urlsArray=url.split("/"); String[] interceptorsArray=interceptors.split("/"); if(interceptorsArray.length<urlsArray.length){ boolean isMatched=true; if(interceptorsArray[interceptorsArray.length-1].equals("*")){ //如果比他url短最后必须要以*结尾 for(int i = 0; i < interceptorsArray.length; i++) { if(!isMatched(urlsArray[i], interceptorsArray[i])){//以短的一个为遍历 isMatched=false; break; } } if(isMatched)return interceptors; }else{ return null; } } if(interceptorsArray.length==urlsArray.length){ //等于 boolean isMatched=true; for (int i = 0; i < interceptorsArray.length; i++) {//长度都一样 if(!isMatched(urlsArray[i], interceptorsArray[i])){ isMatched=false; break; } } if(isMatched){//如果最后匹配完还是相同的话 return interceptors; } } return null; } /** * 匹配每一个节点 * @param urlPart 原始路径节点 * @param intersPart 拦截路径节点 * @return */ private boolean isMatched(String urlPart,String interceptorPart){ return urlPart.equals(interceptorPart)||interceptorPart.equals("*"); } //重写hashcode()和equals方法,要作为map的key @Override public int hashCode() { // TODO Auto-generated method stub return uri.hashCode(); } @Override public boolean equals(Object obj) { if(this==obj){ return true; }else if(obj instanceof URI){ return ((URI) obj).uri.equals(this.uri); } return false; } }这个类里面,主要是封装了URI请求的一些操作,和拦截器匹配等等,覆盖了hashCode()和equals()函数,作为hashmap的key。接下来就是Action类了,这个类里面有3个参数
private Object instance; private Method method; private Class<?>[] arguments;封装了该方法,该类,和该参数
最后我们将URI和Action分别作为MAP的key,value放入到map中!接下来加载interceptor类
private void initInterceptorHander(List<Object> interceptorBeans) { int size=interceptorBeans.size(); for (int i = 0; i <size; i++) { Interceptor interceptor=(Interceptor) interceptorBeans.get(i); InterceptorURI interceptorURI=interceptor.getClass().getAnnotation(InterceptorURI.class); String annotationUri=interceptorURI.url(); interceptor_uri.put(annotationUri, interceptor); } }最总将uri和interceptor关联起来
最后加载我们需要使用的模板
private void initTemplates(FixableConfig config) throws Exception{ String template=config.getInitParameter("template"); if("".equals(template)||template==null){ log.info("You don't have template Parameters ,we will user default JSP template"); template=JSPTEMPLATE; } TemplateFactory templateFactory=FactoryHelper.getInstance().createTemplateFactory(template); templateFactory.init(config); templateFactory.setInstance(templateFactory); }
这样,Dispatcher类的初始化工作就做完了。下一张,我们将会介绍一个请求如何到相关方法,参数的注入,拦截器的工作方式,和拦截器ur的匹配方式
转载请注明出处http://blog.csdn.net/a837199685
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。