这一篇我会介绍一些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. Ubuntu_16.04 配置 Apache Rwrite URL 重写

    Ubuntu Apache配置Rwrite URL重写 0. apache目录

  2. 【转】CoreData以及MagicalRecord (二)

    3. 运行时类与对象 NSManagedObject Managed Object 表示数据文件中的一条记录,每一个Managed Object在内存中对应的实体(Entity)的一个数据表示.Man ...

  3. CV_EXPORTS定义及作用

    CV_EXPORTS 常用如下: class CV_EXPORTS MatExpr; template<typename _Tp> class CV_EXPORTS Size_; CV_E ...

  4. php 图片等比缩放

    /** * @method 图片等比缩放 * @param string $srcImage 源图片路径 * @param string $toFile 目标图片路径 * @param integer ...

  5. javascript 原型 和 原型链

    最近几天,好些新同事来问原型,原型链啥的.本身作为菜鸟的我好像也没有好好整理过这个,这里写写自己的理解. 原型 大家都知道,JavaScript 不包含传统的类继承模型,而是使用 prototype ...

  6. springmvc附件上传核心代码

    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.Comm ...

  7. MVC-05 Model(1)

    在开发应用程序的过程中,经常需要处理许多大大小小的数据,例如,SQL Server数据库存取.连接AD(Active Directory)数据库进行验证.调用外部Web Service取得数据等.除了 ...

  8. 射频识别技术漫谈(13)——Mifare S50与Mifare S70

    Mifare S50和Mifare S70又常被称为Mifare Standard.Mifare Classic.MF1,是遵守ISO14443A标准的卡片中应用最为广泛.影响力最大的的一员.而Mif ...

  9. HDOJ 1423 Greatest Common Increasing Subsequence(dp)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1423 思路分析:[问题定义]给定两个序列A[0, 1,..., m]和B[0, 1, ..., n], ...

  10. 双网卡绑定(suse)

    网卡绑定技术有助于保证高可用性特性并提供其它优势以提高网络性能,Linux双网卡绑定实现就是使用两块网卡虚拟成为一块网卡,这个聚合起来的设备看起来是一个单独的以太网接口设备,就是两块网卡具有相同的IP ...