上一篇文章点击打开链接,介绍了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
时间: 2024-10-14 05:16:23