`

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 >
分享到:
评论

相关推荐

    mvc+linq网站源码

    1. **MVC架构**:MVC模式是一种软件设计模式,主要应用于Web应用开发。Model负责处理数据,View负责显示数据,Controller接收用户输入并调用Model和View进行处理。这种模式提高了代码的可维护性和可测试性。 2. **...

    MVC经典后台管理系统源码-经典必备

    **MVC模式详解** ...通过深入研究这个“MVC经典后台管理系统源码-经典必看”的压缩包,开发者不仅可以掌握MVC模式的实际应用,还能提升对后台管理系统设计和实现的理解,为后续的项目开发积累宝贵经验。

    基于ASP.NET三层架构的学生选课系统 源代码 毕业设计

    【ASP.NET三层架构】 ASP.NET三层架构是一种常见的软件开发模式,用于构建可扩展、易于维护的Web应用程序。...同时,源代码的提供使得学习者有机会深入探究每个层次的实现细节,进一步提升自己的编程技能。

    简易通讯录-MVC构架 v1.0.0.rar

    1. 如何在PHP中实现MVC架构。 2. 如何设计和操作简单的数据库模型。 3. 使用PHP处理HTTP请求并渲染视图。 4. 数据排序的实现方式,包括服务器端和客户端策略。 5. 如何组织和结构化代码以保持良好的可读性和可维护性...

    backbone 源码+API

    学习Backbone.js,开发者需要理解MVC架构的原理,掌握事件驱动编程和数据绑定的概念。同时,对JavaScript原型链、闭包以及异步操作的理解也是必不可少的。通过阅读源码和API文档,开发者可以学习到如何有效地组织...

    spring源码注释中文

    Spring MVC 提供了一个灵活的架构,支持多种视图技术,如 JSP、FreeMarker 和 Velocity。 4. **AOP(面向切面编程)**:Spring 的 AOP 模块提供了面向切面编程的实现,允许开发者定义方法拦截器和切入点,以实现如...

    SpringBoot原理深入及源码剖析开源架构源码2021.pdf

    关于Spring Boot 2021年源码的深入剖析,开源架构源码的探究是一个不断演进的领域。Spring Boot 2021继续秉承简化Spring开发的宗旨,采用了更加现代化和高效的方式来实现自动配置和应用启动流程。Spring Boot 2.0...

    struts-2.1.8.1源码和struts-2.3.15.1源码

    Struts 2是基于Apache Jakarta Struts 1的下一代框架,它融合了WebWork的核心功能,提供了更强大的MVC架构。该框架的关键组件包括Action、Result、Interceptor、ValueStack和Freemarker模板等。Action是业务逻辑的...

    教你阅读Spring源码资源.zip

    同时,结合JDK库的使用,可以深入探究Spring如何利用Java的特性来实现其强大的功能。 总的来说,这个压缩包为学习Spring源码提供了一套完整的资源。从IoC到AOP,从数据访问到Web开发,通过调试代码和实例,我们可以...

    PHP经典源码-餐饮小程序 V5.8.0.rar

    1. 架构设计:了解整体架构,包括MVC(模型-视图-控制器)模式的应用,以及各模块间的交互。 2. 数据库设计:查看数据库表结构,理解如何存储和管理菜单、订单、用户信息等数据。 3. API接口:研究与第三方支付平台...

    ASP.NET源码——[论坛社区]XproerBBS (含源码).zip

    2. **MVC架构**:虽然未明确提及,但现代ASP.NET项目通常会使用MVC(Model-View-Controller)架构,以提高代码的可维护性和可测试性。通过源码,你可以理解MVC模式如何应用于论坛设计。 3. **数据库交互**:论坛...

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

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

    spring源码下载

    它提供了模型-视图-控制器(MVC)架构,帮助开发者将业务逻辑、数据展示和用户交互分离开来。Spring MVC的关键组件包括DispatcherServlet、Controller、Model、View和ViewResolver等。DispatcherServlet作为入口点,...

    asp.net 家教网站源码下载(联盟家教网站)

    这部分可能涉及ASP.NET MVC中的模型(Model)、视图(View)和控制器(Controller)架构,用于处理数据输入和显示。 3. **学生需求发布**:学生可以发布寻找家教的需求,包括科目、时间、地点等。这可能通过表单...

    Spring 2.0 文档 +sping源码

    在这个文档和源码集合中,我们可以深入探究Spring 2.0的核心概念和技术细节。 首先,`.chm`文件是Windows的帮助文件格式,这里包含的是Spring 2.0的官方文档。文档通常会详细介绍框架的架构、配置、API以及如何在...

    苹果在线源码

    【苹果在线源码】是一个与iOS开发相关的主题,特别是针对iPhoneQQ应用的源代码分析。在iOS开发领域,源码的分析和...同时,这也是一个很好的机会去探究大型项目如何组织架构,以及在实际场景下如何解决各种复杂问题。

    zabbix web应用架构分析

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

    IOS应用源码之boydlee-Airmail-917396c.zip

    2. **MVC架构**:Airmail遵循Model-View-Controller(MVC)设计模式,这是一种常见的软件架构,用于组织代码并分离业务逻辑、用户界面和数据。我们将研究源码中的控制器、模型和视图如何协作,以及如何通过MVC实现...

    基于Java+JSP的病历管理系统毕业设计实现+源码毕业设计实现+源码.rar

    3. **MVC(Model-View-Controller)架构**: 常见于Web应用开发,用于分离业务逻辑、数据模型和用户界面。在这个系统中,Model处理数据,View展示信息,Controller协调Model和View的交互。 4. **Servlet**: 虽然未...

Global site tag (gtag.js) - Google Analytics