zoukankan      html  css  js  c++  java
  • 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









  • 相关阅读:
    水晶报表参数字段在代码中赋值
    存储过程编写经验和优化措施
    积分与排名
    大话处理器
    抽象数学
    开普勒:天空的立法者
    Scalable Face Image Retrieval with IdentityBased Quantization and Multireference Reranking
    配色辞典
    图像识别顶级赛事
    Information Geometry
  • 原文地址:https://www.cnblogs.com/lcchuguo/p/5175241.html
Copyright © 2011-2022 走看看