dreamvc框架(二),dreamvc的机制

上一篇文章点击打开链接,介绍了dreamvc的ioc容器集成,这一篇文章我将会给大家介绍dreamvc的机制,


大家都知道Struts2是由filter进入,然后进行分发的,而SpringMVC是由servlet进入然后进行分发的!对于不同的应用服务器,Filter的init函数的执行时间是不同的,例如:tomcat会在tomcat启动的时候执行init函数,而weblogic等一些其他的应用服务器则会在该Filter匹配的url被首次请求的时候加载。而且filte会在servlet前运行


dreamvc不想规定开发者必须由servlet进入还是由filte进入,dreamvc实现了两种方法。由开发者可以自由的选择,看下面的xml配置

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 
	xmlns="http://java.sun.com/xml/ns/javaee" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
	http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

  
	<!-- 配置文件位置,默认为/WEB-INF/applicationContext.xml -->  
    <context-param>  
        <param-name>contextConfigLocation</param-name>  
        <param-value>/WEB-INF/applicationContext.xml</param-value>  
    </context-param>  
    
     <!-- 上下文Spring监听器 -->  
    <listener>  
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  
    </listener>
 

<!--  
  <servlet>

    <servlet-name>DispatcherServlet</servlet-name>
    <servlet-class>org.majorxie.dreamvc.mvc.dispatcher.DispatcherServlet</servlet-class>
    <init-param>
    <param-name>container</param-name>
    <param-value>org.majorxie.dreamvc.ioc.factory.SpringIocFactory</param-value>
    </init-param>
    <init-param>
    <param-name>CodeEnhancement</param-name>
    <param-value>javassist</param-value>
    </init-param>
    
  </servlet>

 
  <servlet-mapping>
    <servlet-name>DispatcherServlet</servlet-name>
    <url-pattern>*.do</url-pattern>
  </servlet-mapping> -->
  <filter>
  <filter-name>DispatcherFilter</filter-name>
  <filter-class>org.majorxie.dreamvc.mvc.dispatcher.DispatcherFilter</filter-class><!-- 选择filter进入,或者选择servlet进入(如上) -->
  <init-param>
    <param-name>container</param-name>
    <param-value>org.majorxie.dreamvc.ioc.factory.SpringIocFactory</param-value><!-- 选择springioc作为ioc容器 -->
    </init-param>
    <init-param>
    <param-name>CodeEnhancement</param-name>
    <param-value>SpringAsm</param-value><!-- 选择SpringAsm或者javassist -->
    
    </init-param>
    <init-param>
    <param-name>template</param-name>
    <param-value></param-value><!-- 选择返回模板这里不填自动选择jsp模板 -->
    </init-param>
    
  </filter>
  
  <filter-mapping>
  <filter-name>DispatcherFilter</filter-name>
  <url-pattern>*.do</url-pattern>
  </filter-mapping>
  
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
</web-app>
开发者选择好事DispatcherFilter还是DispatherServlet之后根据配置就行了。那么dreamvc是怎样做的呢?来看看DispatherServlet和DispatcherFilter的代码

package org.majorxie.dreamvc.mvc.dispatcher;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.GenericServlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.majorxie.dreamvc.tag.Contextconfig.DefaultConfigImpl;
/**
 * dispatcher类,负责初始化任务
 * @author xiezhaodong
 * 2014-10-28
 *
 */
public class DispatcherServlet extends GenericServlet {
	private final Log log=LogFactory.getLog(getClass());	
	
	private Dispatcher dispatcher;
	
	
	public void destroy() {
		log.info("distory!!");
		super.destroy(); 
	}

	@Override
	public void init(ServletConfig config) throws ServletException {
		super.init(config);
		this.dispatcher=new Dispatcher();
		DefaultConfigImpl configImpl=new DefaultConfigImpl(config); 
		dispatcher.init(configImpl);
		
		
	}

	@Override
	public void service(ServletRequest arg0, ServletResponse arg1)
			throws ServletException, IOException {
		HttpServletRequest req=(HttpServletRequest) arg0;
		HttpServletResponse resp=(HttpServletResponse) arg1;
		String method=req.getMethod();
		 if ("GET".equals(method) || "POST".equals(method)) {
			 if(!dispatcher.service(req, resp)){		
				 return;
			 }
		 }
		
		
	}

	
	
}

package org.majorxie.dreamvc.mvc.dispatcher;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.majorxie.dreamvc.tag.Contextconfig.DefaultConfigImpl;
/**
 * filter进入
 * @author xiezhaodong
 *2014-10-31
 */
public class DispatcherFilter implements Filter{
	private Log log=LogFactory.getLog(getClass());
	private Dispatcher dispatcher
	;

	public void destroy() {
		log.info("filter enter destory");
	}

	public void doFilter(ServletRequest arg0, ServletResponse arg1,
			FilterChain arg2) throws IOException, ServletException {
		 HttpServletRequest req = (HttpServletRequest) arg0;
	        HttpServletResponse resp = (HttpServletResponse) arg1;
	        String method = req.getMethod();
	        if ("GET".equals(method) || "POST".equals(method)) {
	            if (!dispatcher.service(req, resp))
	            	arg2.doFilter(req, resp);
	            return;
	        }
	      
		
	}

	public void init(FilterConfig arg0) throws ServletException {
		this.dispatcher=new Dispatcher();
		log.info("filter enter start...");
		DefaultConfigImpl config=new DefaultConfigImpl(arg0);
		dispatcher.init(config);
			
		
	}

}

大家可以看到,实际上真正的加载是交给Dispatcher这个类来完成,这样就实现了分离,那么如何做到得到filter和servlet的机制上的差异呢,关键是Config这个接口,大家看

package org.majorxie.dreamvc.tag.Contextconfig;

import javax.servlet.ServletContext;
/**
 * 2014-10-28
 * @author xiezhaodong
 *
 */
public interface Config {
	
	/**
	 * 得到指定了参数
	 * @return
	 */
	String getInitParameter(String name);
	/**
	 * 
	 * @return servlet context
	 */
	ServletContext getServletContext();

}

这个折扣封装了两个方法,一个是得到参数,一个是得到servletCOntext,然后再有一个默认实现,一个简单是组合适配,就完成了filter和servlet不同的适配

package org.majorxie.dreamvc.tag.Contextconfig;

import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

import javax.servlet.FilterConfig;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
/**
 * 2014-10-28
 * @author xiezhaodong
 *配置默认实现
 *对象适配
 *有3个构造函数,选择需要的构造函数实例化
 *servletconfig用于serlvet进入
 *filterconfig用于filter进入
 *
 */
public class DefaultConfigImpl implements FixableConfig {
	private ServletConfig servletConfig;
	private FilterConfig filterConfig;
	
	public DefaultConfigImpl(ServletConfig servletConfig) {
		this(servletConfig,null);
	}
	public DefaultConfigImpl(FilterConfig filterConfig) {
		this(null,filterConfig);
	}
	
	public DefaultConfigImpl(ServletConfig servletConfig,FilterConfig filterConfig) {
		this.filterConfig =filterConfig;
		this.servletConfig=servletConfig;
	}

	public String getInitParameter(String name) {
		return servletConfig==null?filterConfig.getInitParameter(name):servletConfig.getInitParameter(name);
	}

	public ServletContext getServletContext() {
		return servletConfig==null?filterConfig.getServletContext():servletConfig.getServletContext();
	}

	@SuppressWarnings("unchecked")
	public String[] getInitParameters() {
		Enumeration<String> names=servletConfig==null?filterConfig.getInitParameterNames():servletConfig.getInitParameterNames();
		List<String> list=new ArrayList<String>();
		while(names.hasMoreElements()){
			list.add(this.getInitParameter(names.nextElement()));
		}
		return (String[]) list.toArray();
	}

}

终上所述,dreamvc的两个机制用户可以自行选择来实现。下一篇讲解Dispatcher类到底做了写什么

转载请注明出处http://blog.csdn.net/a837199685




郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。