这一篇我会介绍一些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里面的相应方法,然后对该方法进行检查。keyword。返回值,參数等等。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); }

和载入ioc容器差点儿相同,假设没有指定模板,dreamvc会自己主动选择jsp模板

这样。Dispatcher类的初始化工作就做完了。下一张,我们将会介绍一个请求怎样到相关方法,參数的注入,拦截器的工作方式。和拦截器ur的匹配方式

转载请注明出处http://blog.csdn.net/a837199685



dreamvc框架(三),dispartcher做了些什么的更多相关文章

  1. 从架构演进的角度聊聊Spring Cloud都做了些什么?

    Spring Cloud作为一套微服务治理的框架,几乎考虑到了微服务治理的方方面面,之前也写过一些关于Spring Cloud文章,主要偏重各组件的使用,本次分享主要解答这两个问题:Spring Cl ...

  2. dreamvc框架(一)ioc容器的集成

    我的dreamvc框架最终写得差点儿相同了,借鉴了非常多开源框架,SpringMVC.Struts2等,眼下放在github上面.地址请猛戳我 写得差点儿相同了,是要写一个总结,把自己当时的思路记录下 ...

  3. iOS 中push和pop到底系统做了些什么事

    iOS中的push和pop是一个很常用的视图切换方法,他们是成对出现的, 简而言之,push就是压栈,pop就是出栈! [self.navigationController pushViewContr ...

  4. [转帖]支撑双11每秒17.5万单事务 阿里巴巴对JVM都做了些什么?

    支撑双11每秒17.5万单事务 阿里巴巴对JVM都做了些什么? https://mp.weixin.qq.com/s?__biz=MzA3OTg5NjcyMg==&mid=2661671930 ...

  5. C# 使用Emit实现动态AOP框架 (三)

    目  录 C# 使用Emit实现动态AOP框架 (一) C# 使用Emit实现动态AOP框架 (二) C# 使用Emit实现动态AOP框架 (三) C# 使用Emit实现动态AOP框架 进阶篇之异常处 ...

  6. 手把手和你一起实现一个Web框架实战——EzWeb框架(三)[Go语言笔记]Go项目实战

    手把手和你一起实现一个Web框架实战--EzWeb框架(三)[Go语言笔记]Go项目实战 代码仓库: github gitee 中文注释,非常详尽,可以配合食用 本篇代码,请选择demo3 这一篇文章 ...

  7. Jersey框架三:Jersey对HTTPS的支持

    Jersey系列文章: Jersey框架一:Jersey RESTful WebService框架简介 Jersey框架二:Jersey对JSON的支持 Jersey框架三:Jersey对HTTPS的 ...

  8. 转Rollback后undo到底做了些什么?

    转自:http://biancheng.dnbcw.info/oracle/309191.html Rollback后undo到底做了些什么? 从概念上讲,undo正好与redo相对.当你对数据执行修 ...

  9. 从架构演进的角度聊聊Spring Cloud都做了些什么

    1.从架构演进的角度聊聊Spring Cloud都做了些什么?2.中小型互联网公司微服务实践-经验和教训3.Spring Cloud在国内中小型公司能用起来吗?

随机推荐

  1. js页面跳转 和 js打开新窗口 方法

    js页面跳转 和 js打开新窗口 方法 第一种: 第二种: 第三种: 第四种: 第五种: 1.在原来的窗体中直接跳转用 window.location.href="你所要跳转的页面" ...

  2. JavaSE复习日记 : 循环语句(for/while/do while)

    /* * 循环语句(for循环,while和do while循环) */ /* * for循环语句 * * for循环语法: * for (表达式1;表达式2;表达式3 ){ * java语句 * } ...

  3. MFC 简单实现 DES 算法

    前言 徐旭东老师说过学者就应该对知识抱有敬畏之心,所以我的博客的标题总喜欢加上"简单"二字,就是为了提醒自己,自己所学知识只是皮毛,离真理还远矣. DES 算法 DES算法是密码体 ...

  4. CRM中直接创建SAP订单的实施方案记录

    后台生成订单按钮JS do_alert('正在生成SAP订单,暂停所有操作,同时请不要关闭本窗口!'); var hefid = clientData.urlArgs.entityId; var ur ...

  5. GCD 之 同步 异步 并发

    1. dispatch_async(dispatch_get_global_queue(, ), ^{ // 处理耗时操作的代码块... //通知主线程刷新 dispatch_async(dispat ...

  6. 网络爬虫返回json处理数据

    JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.它基于JavaScript(Standard ECMA-262 3rd Edition - Decembe ...

  7. fedora 安装pylab 并简单绘制三角函数

    pylab 由 三个部分组成:scipy, matplotlab, numpy三部分组成,安装时需要分别安装这三部分,在fedora中,可以使用命令: sudo dnf install python- ...

  8. [dfs+水] hdu 4462 Scaring the Birds

    题意: N*N的矩阵中有M个点能够放稻草人.且给覆盖距离R 每一个稻草人能覆曼哈顿距离R以内的点 问最少须要多少个稻草人 思路: 由于范围非常小,直接能够暴力 注意稻草人所在的位置是不须要被覆盖的 代 ...

  9. 2014多校3 Wow! Such Sequence!段树

    主题链接:http://acm.hdu.edu.cn/showproblem.php? pid=4893 这个问题还真是纠结啊--好久不写线段树的题了.由于这几天学伸展树.然后认为线段树小case了. ...

  10. sql日期转换格式

    Select CONVERT(varchar(100), GETDATE(), 0): 05 16 2006 10:57AM Select CONVERT(varchar(100), GETDATE( ...