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里面的相应方法,然后对该方法进行检查。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做了些什么的更多相关文章
- 从架构演进的角度聊聊Spring Cloud都做了些什么?
Spring Cloud作为一套微服务治理的框架,几乎考虑到了微服务治理的方方面面,之前也写过一些关于Spring Cloud文章,主要偏重各组件的使用,本次分享主要解答这两个问题:Spring Cl ...
- dreamvc框架(一)ioc容器的集成
我的dreamvc框架最终写得差点儿相同了,借鉴了非常多开源框架,SpringMVC.Struts2等,眼下放在github上面.地址请猛戳我 写得差点儿相同了,是要写一个总结,把自己当时的思路记录下 ...
- iOS 中push和pop到底系统做了些什么事
iOS中的push和pop是一个很常用的视图切换方法,他们是成对出现的, 简而言之,push就是压栈,pop就是出栈! [self.navigationController pushViewContr ...
- [转帖]支撑双11每秒17.5万单事务 阿里巴巴对JVM都做了些什么?
支撑双11每秒17.5万单事务 阿里巴巴对JVM都做了些什么? https://mp.weixin.qq.com/s?__biz=MzA3OTg5NjcyMg==&mid=2661671930 ...
- C# 使用Emit实现动态AOP框架 (三)
目 录 C# 使用Emit实现动态AOP框架 (一) C# 使用Emit实现动态AOP框架 (二) C# 使用Emit实现动态AOP框架 (三) C# 使用Emit实现动态AOP框架 进阶篇之异常处 ...
- 手把手和你一起实现一个Web框架实战——EzWeb框架(三)[Go语言笔记]Go项目实战
手把手和你一起实现一个Web框架实战--EzWeb框架(三)[Go语言笔记]Go项目实战 代码仓库: github gitee 中文注释,非常详尽,可以配合食用 本篇代码,请选择demo3 这一篇文章 ...
- Jersey框架三:Jersey对HTTPS的支持
Jersey系列文章: Jersey框架一:Jersey RESTful WebService框架简介 Jersey框架二:Jersey对JSON的支持 Jersey框架三:Jersey对HTTPS的 ...
- 转Rollback后undo到底做了些什么?
转自:http://biancheng.dnbcw.info/oracle/309191.html Rollback后undo到底做了些什么? 从概念上讲,undo正好与redo相对.当你对数据执行修 ...
- 从架构演进的角度聊聊Spring Cloud都做了些什么
1.从架构演进的角度聊聊Spring Cloud都做了些什么?2.中小型互联网公司微服务实践-经验和教训3.Spring Cloud在国内中小型公司能用起来吗?
随机推荐
- :before和:after的内幕以及伪类
pseudo-classes vs pseudo-elements http://m.blog.csdn.net/blog/zhuizhuziwo/7897837
- 命令自动补全模块rlcomplete
rlcomplete定义了针对readline模块的命令自动补全函数. 当在unix平台下导入这个模块之后(前提是readline模块可用),一个Complete的实例会自动生成,并且 ...
- github桌面软件使用教程
github桌面软件使用教程 首先 要先安装 桌面版官网,或者百度搜github windows下载即可 可以再github网站上直接点击,把代码添加的桌面软件中 也可以再左上角添加项目,比如actu ...
- javascript 变量 命名规范 变量的作用域
原文:javascript 变量 命名规范 变量的作用域 大家好,我是小强老师,今天讲解的是变量 变量 小时候我们学过 这个 应用题 : X+1=2; 问 X 等于几? 答案是 1 对了,很聪 ...
- HDU 4931 Happy Three Friends
#include <cstdio> #include <algorithm> using namespace std; int p1,p2,a[6],T; int main() ...
- AutoPy首页、文档和下载 - 跨平台的Python GUI工具包 - 开源中国社区
AutoPy首页.文档和下载 - 跨平台的Python GUI工具包 - 开源中国社区 AutoPy是一个简单跨平台的 Python GUI工具包,可以控制鼠标,键盘,匹配颜色和屏幕上的位图.使用纯A ...
- 发一个讨论帖,如果结果被采纳的话可以给一份adb 代码,以及我封装的ADBLIB
如何在手机没有root 的情况下,获取系统的一些文件,比如 /data/data/xxxx 目录下的文件. 有任何想法的请说出来.
- 74HC595的中文资料
74HC595--具有三态输出锁存功能的8位串行输入.串行/并行输出移位寄存器 本文翻译自NXP的74HC595的datasheet 74HC595和74HCT595是带有存储寄存器和三态输出的8位串 ...
- fopen()函数
1.2 文件的输入输出函数 键盘.显示器.打印机.磁盘驱动器等逻辑设备, 其输入输出都能够通过文件管理的方法来完毕.而在编程时使用最多的要算是磁盘文件, 因此本节主要以磁盘文件为主, 具体介绍Turb ...
- database schema
数据中有4个Schema无法被删除 ● dbo, 具有db_owner或者db_ddl_admin 的用户,新创建对象默认schema就是dbo ● guest , 用来给guest 用户使用,这个s ...