`

MVC架构探究及其源码实现

    博客分类:
  • Java
阅读更多

(1)-理论基础

MVC本来是存在于Desktop程序中的,M是指数据模型,V是指用户界面,C则是控制器。使用MVC的目的是将M和V的实现代码分离,从而使同 一个程序可以使用不同的表现形式。比如一批统计数据你可以分别用柱状图、饼图来表示。C存在的目的则是确保M和V的同步,一旦M改变,V应该同步更新。

  模型-视图-控制器(MVC)是Xerox PARC在八十年代为编程语言Smalltalk-80发明的一种软件设计模式,至今已经被广泛使用。

  我们先来看下经典桌面MVC的模型,为了实现显示和数据的分离,我们在视图和模型之间加入一个控制层,视图只能通过控制器来操作模型,也就是数 据层,一旦数据有更新,模型就会通知视图更新自己。在桌面程序中,用户可以直接和视图进行交互,通过对事件的操作,可以触发视图的各种事件,通过控制器, 以达到更新模型或数据的目的。

经典MVC

  由于Web应用的复杂程度的日益增加,功能也日益庞大,表示层与数据层的分离也显得日益重要。于是MVC这种架构模式被移植到WEB开发中来也 是很自然的事情,然而,Web程序和Desktop程序是有很大区别的,大家都知道,HTTP协议是无连接的,当用户从服务器拿到一个页面之后,整个交互 过程也就完成了,用户无法知道服务器端状态的更新,除非用户再次发送请求。而且,在Web程序中,是没有事件模型支持的,用户的每个动作都必须转化为对服 务器请求。以往的经验,我们经常把视图和控制器组合起来,一个页面既包含程序的业务逻辑,又包含页面的显示信息。然而,视图是经常变化的,业务逻辑确实相 对比较稳定的。为了解决这个问题,比较流行的做法是让控制器执行业务逻辑,从数据层(模型)中抓取显示相关的数据,而视图仅仅是一段显示代码,没有业务逻 辑。由于请求多种多样,而且在控制器到视图的数据转发部分含有很多相同的逻辑,而且为了方便扩展和管理,于是就有人提出了前端控制器的概念,也就是请求分 发器。分发器的作用主要工作就是将一个request分发到一个合适的处理器上,并将处理返回的包含特定信息的视图返回给客户端。下图展现了现在常用的 Web MVC 的标准模型。

WEB MVC

然而,这不是唯一的模型,在ASP.net中,有一种叫做页面控制器的模型。在这种MVC中,并不是令分发器去寻找一个控制器并执行之,而是直接到 达视图并且在继续生成视图之前调用相应的控制器。与传统的MVC模式中的前端控制器对应,这种模式称为页面控制器。页面控制器和前端控制器实现实现之间的 区别在于页面控制器描述的往往是同一个页面中(如类似于控制面板那样的页面)的处理逻辑,不能用于跨多个页面对处理过程进行控制或协调。它是一种Poll 的模型。

Poll

对应的,前端控制器是很典型的一种Push的模型,对同一个请求的几个不同的动作,根据业务逻辑处理后的结果分别被压入到response的各个不同部分。

Push

在下文中,我们仅讨论前端控制器这种方式的具体实现。

(2)-核心组件定义

上文中,我们讨论了MVC的架构的基本原理,这里,我们就要开始着手实现一个简单的WEB MVC前端控制器模型。为了实现这个架构的原型,我们必须引入几个新的概念。

  1. DispatcherServlet:前端控制器,也是整个架构的核心,负责处理和分发请求。
  2. HandlerMapping:处理器映射,他主要包含的是控制器的列表,对于特定的请求,根据HandlerMapping的映射关系,可以找到特定的控制器。最简单的便是url到控制器的映射。
  3. HandlerAdapter:对于不同类型的控制器,该类负责把Handler请求处理的结果统一转换成ModelAndView。
  4. ModelAndView:包含数据和视图的信息,一般包含视图名,和这个视图需要用的数据,这里的Model大家不要误会为模型的概念,它只不过同时包含视图信息及这个视图需要显示的相关信息而已。
  5. ViewResolver:它View名称解析成View对象。
  6. View:定义response显示的详细内容。

HandlerMapping:


  1. package  com.google.mvc.web.servlet;  
  2.   
  3. import  javax.servlet.http.HttpServletRequest;  
  4.   
  5.   
  6. public   interface  HandlerMapping {  
  7.       
  8.     String PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE = HandlerMapping.class .getName() +  ".pathWithinHandlerMapping" ;  
  9.   
  10.     Object getHandler(HttpServletRequest request) throws  Exception;  
  11.   
  12. }  

package com.google.mvc.web.servlet;import javax.servlet.http.HttpServletRequest;public interface HandlerMapping {String PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE = HandlerMapping.class.getName() + ".pathWithinHandlerMapping";Object getHandler(HttpServletRequest request) throws Exception;}  HandlerAdapter:


  1. package  com.google.mvc.web.servlet;  
  2.   
  3. import  javax.servlet.http.HttpServletRequest;  
  4. import  javax.servlet.http.HttpServletResponse;  
  5.   
  6.   
  7. public   interface  HandlerAdapter {  
  8.       
  9.     boolean  supports(Object handler);     
  10.       
  11.     ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws  Exception;  
  12.   
  13.     long  getLastModified(HttpServletRequest request, Object handler);  
  14.   
  15. }  

package com.google.mvc.web.servlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;public interface HandlerAdapter {boolean supports(Object handler);ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;long getLastModified(HttpServletRequest request, Object handler);}  ViewResolver:


  1. package  com.google.mvc.web.servlet;  
  2.   
  3. public   interface  ViewResolver {  
  4.       
  5.     View resolveViewName(String viewName) throws  Exception;  
  6.   
  7. }  

package com.google.mvc.web.servlet;public interface ViewResolver {View resolveViewName(String viewName) throws Exception;}  View:


  1. package  com.google.mvc.web.servlet;  
  2.   
  3. import  java.util.Map;  
  4. import  javax.servlet.http.HttpServletRequest;  
  5. import  javax.servlet.http.HttpServletResponse;  
  6.   
  7. public   interface  View {  
  8.       
  9.     String getContentType();  
  10.       
  11.     void  render(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response)  throws  Exception;  
  12.   
  13. }  

package com.google.mvc.web.servlet;import java.util.Map;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;public interface View {String getContentType();void render(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception;} ModelAndView:


  1. package  com.google.mvc.web.servlet;  
  2.   
  3. import  java.util.HashMap;  
  4. import  java.util.Map;  
  5.   
  6. public   class  ModelAndView {  
  7.       
  8.     private  Object view;      
  9.     private  Map<String, Object> model;  
  10.     private   boolean  cleared;  
  11.   
  12.     public  ModelAndView() {  
  13.     }  
  14.       
  15.     public  ModelAndView(String viewName) {  
  16.         this .view = viewName;  
  17.     }  
  18.       
  19.     public  ModelAndView(View view) {  
  20.         this .view = view;  
  21.     }  
  22.   
  23.     public  ModelAndView(String viewName, Map<String, Object> model) {  
  24.         this .view = viewName;  
  25.         if  (model !=  null ) {  
  26.             addAllObjects(model);  
  27.         }  
  28.     }  
  29.   
  30.   
  31.     public  ModelAndView(View view, Map<String, Object> model) {  
  32.         this .view = view;  
  33.         if  (model !=  null ) {  
  34.             addAllObjects(model);  
  35.         }  
  36.     }  
  37.       
  38.     public  ModelAndView(String viewName, String modelName, Object modelObject) {  
  39.         this .view = viewName;  
  40.         addObject(modelName, modelObject);  
  41.     }  
  42.   
  43.     public  ModelAndView(View view, String modelName, Object modelObject) {  
  44.         this .view = view;  
  45.         addObject(modelName, modelObject);  
  46.     }  
  47.   
  48.     public   void  setViewName(String viewName) {  
  49.         this .view = viewName;  
  50.     }  
  51.   
  52.     public  String getViewName() {  
  53.         return  ( this .view  instanceof  String ? (String)  this .view :  null );  
  54.     }  
  55.   
  56.     public   void  setView(View view) {  
  57.         this .view = view;  
  58.     }  
  59.   
  60.       
  61.     public  View getView() {  
  62.         return  ( this .view  instanceof  View ? (View)  this .view :  null );  
  63.     }  
  64.   
  65.     public   boolean  hasView() {  
  66.         return  ( this .view !=  null );  
  67.     }  
  68.   
  69.     public   boolean  isReference() {  
  70.         return  ( this .view  instanceof  String);  
  71.     }  
  72.   
  73.     protected  Map<String, Object> getModelInternal() {  
  74.         return   this .model;  
  75.     }  
  76.   
  77.     public  Map<String, Object> getModelMap() {  
  78.         if  ( this .model ==  null ) {  
  79.             this .model =  new  HashMap<String, Object>();  
  80.         }  
  81.         return   this .model;  
  82.     }  
  83.       
  84.     public  Map<String, Object> getModel() {  
  85.         return  getModelMap();  
  86.     }  
  87.   
  88.   
  89.     public  ModelAndView addObject(String attributeName, Object attributeValue) {  
  90.         getModelMap().put(attributeName, attributeValue);  
  91.         return   this ;  
  92.     }  
  93.   
  94.       
  95.     public  ModelAndView addObject(Object attributeValue) {  
  96.         getModelMap().put(attributeValue.toString(), attributeValue);  
  97.         return   this ;  
  98.     }  
  99.   
  100.   
  101.     public  ModelAndView addAllObjects(Map<String, Object> modelMap) {  
  102.         getModelMap().putAll(modelMap);  
  103.         return   this ;  
  104.     }  
  105.   
  106.     public   void  clear() {  
  107.         this .view =  null ;  
  108.         this .model =  null ;  
  109.         this .cleared =  true ;  
  110.     }  
  111.   
  112.     public   boolean  isEmpty() {  
  113.         return  ( this .view ==  null  &&  this .model ==  null );  
  114.     }  
  115.   
  116.     public   boolean  wasCleared() {  
  117.         return  ( this .cleared && isEmpty());  
  118.     }  
  119.   
  120.     public  String toString() {  
  121.         StringBuffer buf = new  StringBuffer( "ModelAndView: " );  
  122.         if  (isReference()) {  
  123.             buf.append("reference to view with name '" ).append( this .view).append( "'" );  
  124.         } else  {  
  125.             buf.append("materialized View is [" ).append( this .view).append( ']' );  
  126.         }  
  127.         buf.append("; model is " ).append( this .model);  
  128.         return  buf.toString();  
  129.     }  
  130.   
  131. }  

package com.google.mvc.web.servlet;import java.util.HashMap;import java.util.Map;public class ModelAndView {private Object view;private Map<String, Object> model;private boolean cleared;public ModelAndView() {}public ModelAndView(String viewName) {this.view = viewName;}public ModelAndView(View view) {this.view = view;}public ModelAndView(String viewName, Map<String, Object> model) {this.view = viewName;if (model != null) {addAllObjects(model);}}public ModelAndView(View view, Map<String, Object> model) {this.view = view;if (model != null) {addAllObjects(model);}}public ModelAndView(String viewName, String modelName, Object modelObject) {this.view = viewName;addObject(modelName, modelObject);}public ModelAndView(View view, String modelName, Object modelObject) {this.view = view;addObject(modelName, modelObject);}public void setViewName(String viewName) {this.view = viewName;}public String getViewName() {return (this.view instanceof String ? (String) this.view : null);}public void setView(View view) {this.view = view;}public View getView() {return (this.view instanceof View ? (View) this.view : null);}public boolean hasView() {return (this.view != null);}public boolean isReference() {return (this.view instanceof String);}protected Map<String, Object> getModelInternal() {return this.model;}public Map<String, Object> getModelMap() {if (this.model == null) {this.model = new HashMap<String, Object>();}return this.model;}public Map<String, Object> getModel() {return getModelMap();}public ModelAndView addObject(String attributeName, Object attributeValue) {getModelMap().put(attributeName, attributeValue);return this;}public ModelAndView addObject(Object attributeValue) {getModelMap().put(attributeValue.toString(), attributeValue);return this;}public ModelAndView addAllObjects(Map<String, Object> modelMap) {getModelMap().putAll(modelMap);return this;}public void clear() {this.view = null;this.model = null;this.cleared = true;}public boolean isEmpty() {return (this.view == null && this.model == null);}public boolean wasCleared() {return (this.cleared && isEmpty());}public String toString() {StringBuffer buf = new StringBuffer("ModelAndView: ");if (isReference()) {buf.append("reference to view with name '").append(this.view).append("'");} else {buf.append("materialized View is [").append(this.view).append(']');}buf.append("; model is ").append(this.model);return buf.toString();}}

这几个类由DispatcherServlet管理和控制,以下是它们的序列图:
mvc

这些对象需要怎么注入到系统中呢?这里当然少不了配置文件的支持,现在比较流行的MVC框架大多可以使用Spring作为其IOC容器,为了简单起见,我们自己决定模拟Spring简单地实现一个配置管理容器,用于管理我们的各种对象资源。

(3)-WebApplicationContext

直接利用web.xml去配置和定义我们的对象组件显然是不灵活和不方便扩展的,由于我们系统中将会需要配置很多个不同的对象资源,比如控制器,View 对象,HandlerMapping对象等等,如何对它们进行管理,如何能让我们的前端控制器访问和利用到到它们便是我们不得不面对的问题。还好,现在有 了Spring,现在很多流行的MVC框架都支持使用Spring对自己容器里的对象资源进行管理。尽管Spring千好万好,我们这里还是决定不使用 它,而是自己来写一个对象容器来管理我们的相关资源,这样我们不仅可以了解对象资源配置管理的细节,还可以顺带学习一下Spring等IOC容器的实现原 理。当然,我们这里的实现方案将会尽可能的简单。
如下便是我们的WebApplicationContext类的实现,它能够自动查找WEB- INF路径下所有以config结尾的xml文件,并把其中定义的对象抽取出来,放到Application作用域中,由于我们这里只是个Sample, 不需要考虑太多的并发的情况,所有对象的类型,我们都是用Singleton,也就是定义的每个对象都为所有的请求和Servlet共享。 WebApplicationContext中还定义了一个很有用的方法,beansOfType(Class<T>),该方法用于查找出系 统中定义的所有的属于当前类型的所有对象资源。


  1. package  com.google.mvc.web.context;  
  2.   
  3. import  java.io.InputStream;  
  4. import  java.lang.reflect.Method;  
  5.   
  6. import  java.util.HashMap;  
  7. import  java.util.Locale;  
  8. import  java.util.Map;  
  9. import  java.util.Set;  
  10. import  java.util.concurrent.ConcurrentHashMap;  
  11.   
  12. import  javax.servlet.ServletContext;  
  13. import  javax.xml.parsers.DocumentBuilder;  
  14. import  javax.xml.parsers.DocumentBuilderFactory;  
  15. import  javax.xml.parsers.ParserConfigurationException;  
  16.   
  17. import  org.apache.log4j.Logger;  
  18. import  org.w3c.dom.Document;  
  19. import  org.w3c.dom.Element;  
  20. import  org.w3c.dom.NodeList;  
  21.   
  22. public   class  WebApplicationContext {  
  23.       
  24.     private   static   final  Logger LOGGER = Logger.getLogger(WebApplicationContext. class );   
  25.     private   static   final  String WEB_APPLICATION_CONTEXT_ATTRIBUTE = WebApplicationContext. class .getName() +  ".CONTEXT" ;  
  26.     private  Map<String, Object> cacheMap;  
  27.     private  ServletContext servletContext;  
  28.     private  DocumentBuilder builder;      
  29.   
  30.     public  WebApplicationContext(ServletContext servletContext) {  
  31.         this .servletContext = servletContext;                 
  32.         DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();  
  33.         try  {  
  34.             builder = factory.newDocumentBuilder();  
  35.         } catch  (ParserConfigurationException e) {  
  36.             LOGGER.error("Can't load dom builder" , e);  
  37.         }  
  38.     }  
  39.   
  40.     public   void  init() {          
  41.         ServletContext context = getServletContext();  
  42.         Set<?> set = context.getResourcePaths("/WEB-INF" );  
  43.         Object map = servletContext.getAttribute(WEB_APPLICATION_CONTEXT_ATTRIBUTE);  
  44.         if  (map !=  null ) {  
  45.             cacheMap = (Map<String, Object>) map;  
  46.         } else  {  
  47.             cacheMap = new  ConcurrentHashMap<String, Object>();  
  48.             servletContext.setAttribute(WEB_APPLICATION_CONTEXT_ATTRIBUTE, cacheMap);             
  49.             for  (Object o : set) {  
  50.                 String path = (String) o;  
  51.                 if  (path.endsWith( "config.xml" )) {  
  52.                     try  {                         
  53.                         loadResource(servletContext.getResourceAsStream(path));  
  54.                     } catch  (Exception ex) {  
  55.                         LOGGER.error("Can't load resource "  + path);  
  56.                     }  
  57.                 }  
  58.             }  
  59.         }  
  60.     }  
  61.       
  62.     private   void  loadResource(InputStream resource)  throws  Exception{  
  63.         Document doc = builder.parse(resource);  
  64.         Element root = doc.getDocumentElement();  
  65.           
  66.         NodeList nodeList = root.getElementsByTagName("bean" );    
  67.         for ( int  i =  0 ; i < nodeList.getLength(); i++){             
  68.             Element el = (Element)nodeList.item(i);           
  69.             String id = el.getAttribute("id" );  
  70.             String className = el.getAttribute("class" );              
  71.             Class<?> clazz = this .getClass().getClassLoader().loadClass(className);  
  72.             Object o = createBean(id, clazz);             
  73.             NodeList propertyList = el.getElementsByTagName("property" );  
  74.             for ( int  j =  0 ; j < propertyList.getLength(); j++){  
  75.                 Element prop = (Element)propertyList.item(j);                 
  76.                 String methodName = getMethodName(prop.getAttribute("name" ));                 
  77.                 Method m = clazz.getMethod(methodName, String.class );                 
  78.                 String property = prop.getAttribute("value" );  
  79.                 Object dependObject = cacheMap.get(property);  
  80.                 if (dependObject !=  null ){  
  81.                     m.invoke(o, dependObject);  
  82.                 } else  {  
  83.                     m.invoke(o, property);  
  84.                 }                         
  85.             }             
  86.             cacheMap.put(id, o);  
  87.         }         
  88.     }  
  89.       
  90.     protected  String getMethodName(String methodName){  
  91.         StringBuilder sb = new  StringBuilder();  
  92.         sb.append("set" );  
  93.         sb.append(methodName.substring(0 1 ).toUpperCase(Locale.US));  
  94.         sb.append(methodName.substring(1 ));  
  95.         return  sb.toString();  
  96.     }  
  97.       
  98.     public  Object createBean(Class<?> clazz)  throws  Exception{          
  99.         return  createBean(clazz.getCanonicalName(), clazz);  
  100.     }  
  101.       
  102.     public  Object createBean(String name, Class<?> clazz)  throws  Exception{             
  103.         Object o = cacheMap.get(name);        
  104.         if (o ==  null ){  
  105.             o = clazz.newInstance();  
  106.             if (o  instanceof  WebApplicationContextAware){  
  107.                 ((WebApplicationContextAware)o).setWebApplicationContext(this );  
  108.             }  
  109.             cacheMap.put(name, o);    
  110.         }     
  111.         LOGGER.info(name + "="  + clazz.getCanonicalName());  
  112.         return  o;  
  113.     }  
  114.       
  115.     public  Object getBean(String beanName){  
  116.         return  servletContext.getAttribute(beanName);  
  117.     }  
  118.       
  119.     public  ServletContext getServletContext() {  
  120.         return  servletContext;  
  121.     }  
  122.   
  123.     public   void  setServletContext(ServletContext servletContext) {  
  124.         this .servletContext = servletContext;  
  125.     }  
  126.       
  127.     public  <T> Map<String, T> beansOfType(Class<T> clazz){  
  128.         Map<String, T> map = new  HashMap<String, T>();  
  129.         for (String key : cacheMap.keySet()){  
  130.             Object o = cacheMap.get(key);  
  131.             if (clazz.isAssignableFrom(o.getClass())){  
  132.                 map.put(key, (T)o);  
  133.             }  
  134.         }  
  135.         return  map;  
  136.     }  
  137.   
  138. }  

package com.google.mvc.web.context;import java.io.InputStream;import java.lang.reflect.Method;import java.util.HashMap;import java.util.Locale;import java.util.Map;import java.util.Set;import java.util.concurrent.ConcurrentHashMap;import javax.servlet.ServletContext;import javax.xml.parsers.DocumentBuilder;import javax.xml.parsers.DocumentBuilderFactory;import javax.xml.parsers.ParserConfigurationException;import org.apache.log4j.Logger;import org.w3c.dom.Document;import org.w3c.dom.Element;import org.w3c.dom.NodeList;public class WebApplicationContext {private static final Logger LOGGER = Logger.getLogger(WebApplicationContext.class);private static final String WEB_APPLICATION_CONTEXT_ATTRIBUTE = WebApplicationContext.class.getName() + ".CONTEXT";private Map<String, Object> cacheMap;private ServletContext servletContext;private DocumentBuilder builder;public WebApplicationContext(ServletContext servletContext) {this.servletContext = servletContext;DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();try {builder = factory.newDocumentBuilder();} catch (ParserConfigurationException e) {LOGGER.error("Can't load dom builder", e);}}public void init() {ServletContext context = getServletContext();Set<?> set = context.getResourcePaths("/WEB-INF");Object map = servletContext.getAttribute(WEB_APPLICATION_CONTEXT_ATTRIBUTE);if (map != null) {cacheMap = (Map<String, Object>) map;} else {cacheMap = new ConcurrentHashMap<String, Object>();servletContext.setAttribute(WEB_APPLICATION_CONTEXT_ATTRIBUTE, cacheMap);for (Object o : set) {String path = (String) o;if (path.endsWith("config.xml")) {try {loadResource(servletContext.getResourceAsStream(path));} catch (Exception ex) {LOGGER.error("Can't load resource " + path);}}}}}private void loadResource(InputStream resource) throws Exception{Document doc = builder.parse(resource);Element root = doc.getDocumentElement();NodeList nodeList = root.getElementsByTagName("bean");for(int i = 0; i < nodeList.getLength(); i++){Element el = (Element)nodeList.item(i);String id = el.getAttribute("id");String className = el.getAttribute("class");Class<?> clazz = this.getClass().getClassLoader().loadClass(className);Object o = createBean(id, clazz);NodeList propertyList = el.getElementsByTagName("property");for(int j = 0; j < propertyList.getLength(); j++){Element prop = (Element)propertyList.item(j);String methodName = getMethodName(prop.getAttribute("name"));Method m = clazz.getMethod(methodName, String.class);String property = prop.getAttribute("value");Object dependObject = cacheMap.get(property);if(dependObject != null){m.invoke(o, dependObject);} else {m.invoke(o, property);}}cacheMap.put(id, o);}}protected String getMethodName(String methodName){StringBuilder sb = new StringBuilder();sb.append("set");sb.append(methodName.substring(0, 1).toUpperCase(Locale.US));sb.append(methodName.substring(1));return sb.toString();}public Object createBean(Class<?> clazz) throws Exception{return createBean(clazz.getCanonicalName(), clazz);}public Object createBean(String name, Class<?> clazz) throws Exception{Object o = cacheMap.get(name);if(o == null){o = clazz.newInstance();if(o instanceof WebApplicationContextAware){((WebApplicationContextAware)o).setWebApplicationContext(this);}cacheMap.put(name, o);}LOGGER.info(name + "=" + clazz.getCanonicalName());return o;}public Object getBean(String beanName){return servletContext.getAttribute(beanName);}public ServletContext getServletContext() {return servletContext;}public void setServletContext(ServletContext servletContext) {this.servletContext = servletContext;}public <T> Map<String, T> beansOfType(Class<T> clazz){Map<String, T> map = new HashMap<String, T>();for(String key : cacheMap.keySet()){Object o = cacheMap.get(key);if(clazz.isAssignableFrom(o.getClass())){map.put(key, (T)o);}}return map;}} 我们再来看一下*.config.xml文件里对象资源的定义示例:

  1. <? xml   version = "1.0"   encoding = "UTF-8" ?>   
  2. < beans >      
  3.     < bean   id = "ControllerAdapter"   class = "com.google.mvc.web.servlet.mvc.ControllerHandlerAdapter"   />     
  4.     < bean   id = "HttpRequestAdapter"   class = "com.google.mvc.web.servlet.mvc.HttpRequestHandlerAdapter"   />    
  5.     < bean   id = "ViewResolver"   class = "com.google.mvc.web.servlet.mvc.DefaultViewResolver" >   
  6.         < property   name = "viewClass"   value = "com.google.mvc.web.servlet.mvc.InternalResourceView" />   
  7.         < property   name = "prefix"   value = "/WEB-INF/" />   
  8.         < property   name = "suffix"   value = ".jsp" />   
  9.     </ bean >    
  10.     < bean   id = "login.do"   class = "com.google.mvc.web.sample.LoginController"   />   
  11.     < bean   id = "hello.do"   class = "com.google.mvc.web.sample.HelloController"   />      
  12.     < bean   id = "404"   class = "com.google.mvc.web.servlet.mvc.HandlerFor404"   />    
  13.   
  14. </ beans >   

<?xml version="1.0" encoding="UTF-8"?><beans>      <bean id="ControllerAdapter" class="com.google.mvc.web.servlet.mvc.ControllerHandlerAdapter" />      <bean id="HttpRequestAdapter" class="com.google.mvc.web.servlet.mvc.HttpRequestHandlerAdapter" />     <bean id="ViewResolver" class="com.google.mvc.web.servlet.mvc.DefaultViewResolver">        <property name="viewClass" value="com.google.mvc.web.servlet.mvc.InternalResourceView"/>        <property name="prefix" value="/WEB-INF/"/>        <property name="suffix" value=".jsp"/>    </bean> <bean id="login.do" class="com.google.mvc.web.sample.LoginController" /><bean id="hello.do" class="com.google.mvc.web.sample.HelloController" />       <bean id="404" class="com.google.mvc.web.servlet.mvc.HandlerFor404" /> </beans> 如果哪个对象资源需要在运行过程中使用到WebApplicationContext的资源及方法,只需实现接口 WebApplicationContextAware即可,一旦实现了该接口,当前的WebApplicationContext会被自动的注入到此对 象资源中。


  1. package  com.google.mvc.web.context;  
  2.   
  3. public   interface  WebApplicationContextAware {  
  4.       
  5.     void  setWebApplicationContext(WebApplicationContext wac);  
  6.   

(4)-前端控制器

前端控制器是整个MVC框架中最为核心的一块,它主要用来拦截符合要求的外部请求,并把请求分发到不同的控制器去处理,根据控制器处理后的结果,生 成相应的响应发送到客户端。前端控制器既可以使用Filter实现(Struts2采用这种方式),也可以使用Servlet来实现。这里我们就采用后一 种方式来实现我们的MVC框架。

 ds

1.配置web.xml,使得我们的前端控制器可以拦截所有符合要求的用户请求,这里我们的前端控制器能处理所有以.do结尾的用户请求。 


  1. <? xml   version = "1.0"   encoding = "ISO-8859-1" ?>   
  2. < web-app   xmlns = "http://java.sun.com/xml/ns/javaee"   
  3.    xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"   
  4.    xsi:schemaLocation = "http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"   
  5.    version = "2.5" >    
  6.   
  7.     < description > MVC Sample </ description >   
  8.     < display-name > MVC </ display-name >   
  9.       
  10.     < servlet >   
  11.       < servlet-name > DispatcherServlet </ servlet-name >   
  12.       < servlet-class > com.google.mvc.web.servlet.DispatcherServlet </ servlet-class >   
  13.     </ servlet >      
  14.   
  15.     < servlet-mapping >   
  16.         < servlet-name > DispatcherServlet </ servlet-name >
分享到:
评论

相关推荐

    Spring技术内幕:深入解析Spring架构与设计原理(第2部分)

    你不仅能从木书中参透Spring框架的优秀架构和设计思想,而且还能从Spring优雅的实现源码中一窥Java语言的精髓。此外,《Spring技术内幕:深入解析Spring架构与设计原理》还展示了阅读源代码的卓越方法,不仅授你以鱼...

    zabbix web应用架构分析pdf版

    本文通过源码分析,探究zabbix web应用的整体架构,所有分析基于zabbix 3.0.10进行。 总体而言,zabbix web应用使用PHP开发,大量应用OOP方法,主要采用mvc架构,同时包含一套遵循JSON-RPC 2.0协议的web API。 ...

    zabbix web应用架构分析

    本文通过源码分析,探究zabbix web应用的整体架构,所有分析基于zabbix 3.0.10进行。 总体而言,zabbix web应用使用PHP开发,大量应用OOP方法,主要采用mvc架构,同时包含一套遵循JSON-RPC 2.0协议的web API。 由于...

    Spring技术内幕:深入解析Spring架构与设计原理(第1部分)

    你不仅能从木书中参透Spring框架的优秀架构和设计思想,而且还能从Spring优雅的实现源码中一窥Java语言的精髓。此外,《Spring技术内幕:深入解析Spring架构与设计原理》还展示了阅读源代码的卓越方法,不仅授你以鱼...

    Spring技术内幕:深入解析Spring架构与设计原理(第一部分)

    你不仅能从木书中参透Spring框架的优秀架构和设计思想,而且还能从Spring优雅的实现源码中一窥Java语言的精髓。此外,《Spring技术内幕:深入解析Spring架构与设计原理》还展示了阅读源代码的卓越方法,不仅授你以鱼...

    Spring技术内幕:深入解析Spring架构与设计原理

    你不仅能从木书中参透Spring框架的优秀架构和设计思想,而且还能从Spring优雅的实现源码中一窥Java语言的精髓。此外,《Spring技术内幕:深入解析Spring架构与设计原理》还展示了阅读源代码的卓越方法,不仅授你以鱼...

    Spring技术内幕:深入解析Spring架构与设计原理 1/2

    你不仅能从木书中参透spring框架的优秀架构和设计思想,而且还能从spring优雅的实现源码中一窥java语言的精髓。此外,本书还展示了阅读源代码的卓越方法,不仅授你以鱼,而且还授你以渔!..  如果你以一种淡定的心态...

    Spring技术内幕:深入解析Spring架构与设计原理 2/2

    你不仅能从木书中参透spring框架的优秀架构和设计思想,而且还能从spring优雅的实现源码中一窥java语言的精髓。此外,本书还展示了阅读源代码的卓越方法,不仅授你以鱼,而且还授你以渔!..  如果你以一种淡定的...

    SPRING3技术内幕

    你不仅能从木书中参透Spring框架的优秀架构和设计思想,而且还能从Spring优雅的实现源码中一窥Java语言的精髓。此外,《Spring技术内幕:深入解析Spring架构与设计原理》还展示了阅读源代码的卓越方法,不仅授你以鱼...

    SPRING3技术内幕.z01

    你不仅能从木书中参透Spring框架的优秀架构和设计思想,而且还能从Spring优雅的实现源码中一窥Java语言的精髓。此外,《Spring技术内幕:深入解析Spring架构与设计原理》还展示了阅读源代码的卓越方法,不仅授你以鱼...

    Spring技术内幕

    你不仅能从木书中参透Spring框架的优秀架构和设计思想,而且还能从Spring优雅的实现源码中一窥Java语言的精髓。此外,本书还展示了阅读源代码的卓越方法,不仅授你以鱼,而且还授你以渔!, 如果你以一种淡定的心态...

    还在死记硬背面试题,面试官问我题的时候,我哭了,试试这一套,精心提炼核心重点内容简化实战应用面试宝典10秒钟搞定一道面试题!

    方法,网络编程,Tomcat,Http,Maven,Mvc三层架构,Servlet,Cookie/Session,Web,Filter,监听器,MyBatis,SpringMVC,Redis,微服务开发,SSM框架,JavaWeb,JavaSE,中间件,运维,源码探究,设计模式,以及等多种应用题...

Global site tag (gtag.js) - Google Analytics