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

时间: 2024-10-08 15:32:00

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

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

我的dreamvc框架终于写得差不多了,借鉴了很多开源框架,SpringMVC.Struts2等,目前放在github上面.地址请猛戳我 写得差不多了,是要写一个总结,把自己当时的思路记录下来!还有更多的工作要做! (一) 首先,IOC容器作为管理bean的重要工具,我们在日常的开发当中经常用到,最常用的就属SPRINGIOC了吧!当然,如果开发者不原理是用SPRINGIOC,那么你可以实现自己的容器,或者是用其他的3方ioc工具,只要实现dreamvc提供的IocFactory或者继承Abst

关于driver_register做了些什么

现在进入driver_register()函数去看看.在driver_register() 中,调用了driver_find(drv->name, drv->bus)函数,这里是干啥呢?这里是先去驱动打算挂牌的地方先查找一下,这个驱动是否已经挂牌(注册)过了.在哪里查找呢?代码中写得很清楚,去bus->p->drivers_kset中查找,看到这里,我决定这里不要再继续展开细细的分析,否则永远都无法把内核看明白,有时候必须对细节很了解,有时候只要明白他的工作原理就可以,不必太细碎.

企业级应用框架(三)三层架构之数据访问层的改进以及测试DOM的发布

在上一篇我们在宏观概要上对DAL层进行了封装与抽象.我们的目的主要有两个:第一,解除BLL层对DAL层的依赖,这一点我们通过定义接口做到了:第二,使我们的DAL层能够支持一切数据访问技术,如Ado.net,EF,linq To Sql,这一点我们实现的不是很完美,仍有很大的改进空间,本文将加以改进. 在此之前我们来看一下我们最新的dom(PS:经过两天的赶工,我们的dom已经相对成熟,其中BLL层已经被我高度抽象化了,并且引进了业务上文文的概念:DAL层除了具体的技术实现尚为完成,其他方面已经相

一张图告诉你广电总局这些年都做了些什么~

广电总局,那些年的禁令!国家新闻出版广电总局是国务院直属机构,我们最熟悉的莫过于电影开场时必然会出现的金色龙形长城标志.那么,一张图,让你看清广电总局这些年做了什么事…… 一张图告诉你广电总局这些年都做了些什么-,布布扣,bubuko.com

类集框架(三)

1. Map和HashMap的使用方法 2. JDK帮助文档的使用方法 1. Map和HashMap的使用方法 2. JDK帮助文档的使用方法 帮助文档下载chm格式的英文版, 在索引里面搜索Map 1 import java.util.Map; 2 import java.util.HashMap; 3 4 public class Test{ 5 public static void main(String args []){ 6 HashMap<String,String> hashMa

【dotnet跨平台】&amp;quot;dotnet restore&amp;quot;和&amp;quot;dotnet run&amp;quot;都做了些什么?

[dotnet跨平台]"dotnet restore"和"dotnet run"都做了些什么? 前言: 关于dotnet跨平台的相关内容.能够參考:跨平台.NET Core--微软开源方向 当中..net core基础库叫CoreFX:https://github.com/dotnet/corefx,.net core执行时叫CoreCLR:https://github.com/dotnet/coreCLR, asp.net core各组件库:https://git

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

转自:http://biancheng.dnbcw.info/oracle/309191.html Rollback后undo到底做了些什么? 从概念上讲,undo正好与redo相对.当你对数据执行修改时,数据库会生成undo信息,这样万一你执行的事务或语句由于某种原因失败了,或者如果你用一条rollback语句请求回滚,就可以利用这些undo信息将数据还原到修改前的样子.Redo用于在失败时还原事务(即恢复事务),undo则用于取消一条语句或者一组语句的作用.与redo不同,undo在数据库内

电脑在开机的时候都做了些什么

首先嘛,开机对于大家来说也就是捅一下开机按钮,然后电脑开始嗡嗡叫,各种风扇转起来,显示器上显示了一个LOGO,最后就看到了Win7的启动动画.这个过程中,电脑详细都做了些什么呢?我在这里详细的说一说我的了解.(注意这只是我的了解,我还是很严谨的哦) 1.开机之后,主板的芯片组会给CPU发送一个RESET信号,CPU会挂起,并不马上执行指令(CS:EIP=0xFFFF:0x0000) 这个时候CPU完成初始化,内部恢复到初始状态. 等芯片组检测到电源已经稳定供电了,芯片组就撤去RESET信号,CP

asp.net使用MVC4框架基于NPOI做导出数据到Excel表

NPOI 是 POI 项目的 .NET 版本.POI是一个开源的Java读写Excel.WORD等微软OLE2组件文档的项目. 使用 NPOI 你就可以在没有安装 Office 或者相应环境的机器上对 WORD/EXCEL 文档进行读写.NPOI是构建在POI 3.x版本之上的,它可以在没有安装Office的情况下对Word/Excel文档进行读写操作.使用 NPOI 你就可以在没有安装 Office 或者相应环境的机器上对 WORD/EXCEL 文档进行读写.NPOI是构建在POI 3.x版本