这一篇我会介绍一些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. 如何最简单的优化MySql

    1.创建索引,一定要根据实际情况来创建,如果是连接表查询,如一个主帐号连接多个子帐号,可以考虑两个或三个以上的多索引: 2.合理利用时间排序,由于大多数表格用时间来排序,数据量相当大的时候,在时间列上 ...

  2. Android ListView 删除动画

    Android 的ListView在删除条目时,被删除的条目直接消失,比较生硬,在此实现一下删除动画,大家一起探讨:主要实现原理即是通过Animator来实现被删除条目的动画效果,然后在动画结束时通过 ...

  3. Android 开发笔记 “弹出框”

    AlertDialog.Builder builder = new AlertDialog.Builder(Activity.this); builder.setMessage("Are y ...

  4. mysql 组合索引

    MySQL单列索引是我们使用MySQL数据库中经常会见到的,MySQL单列索引和组合索引的区别可能有很多人还不是十分的了解,下面就为您分析两者的主要区别,供您参考学习. 为了形象地对比两者,再建一个表 ...

  5. bzoj 1047 : [HAOI2007]理想的正方形 单调队列dp

    题目链接 1047: [HAOI2007]理想的正方形 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2369  Solved: 1266[Submi ...

  6. [LeetCode]题解(python):108-Convert Sorted Array to Binary Search Tree

    题目来源: https://leetcode.com/problems/convert-sorted-array-to-binary-search-tree/ 题意分析: 给出一个排好序的数组,根据这 ...

  7. SubLime2 win + mac keygen

    参考 http://www.cnblogs.com/snandy/archive/2013/05/08/3068059.html http://www.freebuf.com/tools/6434.h ...

  8. LintCode-字符串查找

    题目描述: 对于一个给定的 source 字符串和一个 target 字符串,你应该在 source 字符串中找出 target 字符串出现的第一个位置(从0开始).如果不存在,则返回 -1. 说明 ...

  9. tomcat应用转到weblogic上时的问题

    昨天将一个tomcat环境下调试通过的报表demo应用发布到weblogic上做测试,结果发现好多问题.总结了一下,主要有这么几点: 1.使用log4j的问题. tomcat应用直接发布到weblog ...

  10. PowerPoint2003/2007幻灯片常用快捷键大全

    熟习掌握PowerPoint快捷键不仅可以对我们在制作幻灯片的时候更加熟练节省时间.而且在我们演示PPT文稿的时候,也不需要停下演讲去调试菜单工具来切换下一张,我们只需要轻轻的按一下键盘即可轻松切换P ...