Introduction
Spring MVC is a powerful web framework that implements the Model-View-Controller pattern.In this article,I’ll explore the implementation of a simplified Spring MVC framework through my miniSpring project,which captures the essential features of Spring MVC while maintaining clarity and simplicity.
src/com/yaruyng/web/├── servlet/│ ├── DispatcherServlet.java│ ├── HandlerMapping.java│ ├── HandlerAdapter.java│ ├── ModelAndView.java│ ├── ViewResolver.java│ └── View.java├── method/├── context/└── RequestMapping.javasrc/com/yaruyng/web/ ├── servlet/ │ ├── DispatcherServlet.java │ ├── HandlerMapping.java │ ├── HandlerAdapter.java │ ├── ModelAndView.java │ ├── ViewResolver.java │ └── View.java ├── method/ ├── context/ └── RequestMapping.javasrc/com/yaruyng/web/ ├── servlet/ │ ├── DispatcherServlet.java │ ├── HandlerMapping.java │ ├── HandlerAdapter.java │ ├── ModelAndView.java │ ├── ViewResolver.java │ └── View.java ├── method/ ├── context/ └── RequestMapping.java
Enter fullscreen mode Exit fullscreen mode
The Front Controller:DispatcherServlet
The DispatcherServlet acts as the front controller in our MVC implements:
<span>public</span> <span>class</span> <span>DispatcherServlet</span> <span>extends</span> <span>HttpServlet</span> <span>{</span><span>private</span> <span>WebApplicationContext</span> <span>webApplicationContext</span><span>;</span><span>private</span> <span>HandlerMapping</span> <span>handlerMapping</span><span>;</span><span>private</span> <span>HandlerAdapter</span> <span>handlerAdapter</span><span>;</span><span>private</span> <span>ViewResolver</span> <span>viewResolver</span><span>;</span><span>@Override</span><span>public</span> <span>void</span> <span>init</span><span>(</span><span>ServletConfig</span> <span>config</span><span>)</span> <span>throws</span> <span>ServletException</span> <span>{</span><span>super</span><span>.</span><span>init</span><span>(</span><span>config</span><span>);</span><span>this</span><span>.</span><span>parentApplicationContext</span> <span>=</span> <span>(</span><span>WebApplicationContext</span><span>)</span> <span>this</span><span>.</span><span>getServletContext</span><span>()</span><span>.</span><span>getAttribute</span><span>(</span><span>WebApplicationContext</span><span>.</span><span>ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE</span><span>);</span><span>this</span><span>.</span><span>sContextConfigLocation</span> <span>=</span> <span>config</span><span>.</span><span>getInitParameter</span><span>(</span><span>"contextConfigLocation"</span><span>);</span><span>this</span><span>.</span><span>webApplicationContext</span> <span>=</span> <span>new</span> <span>AnnotationConfigWebApplicationContext</span><span>(</span><span>sContextConfigLocation</span><span>,</span><span>this</span><span>.</span><span>parentApplicationContext</span><span>);</span><span>Refresh</span><span>();</span><span>}</span><span>protected</span> <span>void</span> <span>doDispatch</span><span>(</span><span>HttpServletRequest</span> <span>request</span><span>,</span> <span>HttpServletResponse</span> <span>response</span><span>)</span><span>throws</span> <span>Exception</span> <span>{</span><span>HttpServletRequest</span> <span>processedRequest</span> <span>=</span> <span>request</span><span>;</span><span>HandlerMethod</span> <span>handlerMethod</span> <span>=</span> <span>null</span><span>;</span><span>ModelAndView</span> <span>mv</span> <span>=</span> <span>null</span><span>;</span><span>// 1. Get handler for request</span><span>handlerMethod</span> <span>=</span> <span>this</span><span>.</span><span>handlerMapping</span><span>.</span><span>getHandler</span><span>(</span><span>processedRequest</span><span>);</span><span>if</span><span>(</span><span>handlerMethod</span> <span>==</span> <span>null</span><span>)</span> <span>{</span><span>return</span><span>;</span><span>}</span><span>// 2. Execute handler with adapter</span><span>HandlerAdapter</span> <span>ha</span> <span>=</span> <span>this</span><span>.</span><span>handlerAdapter</span><span>;</span><span>mv</span> <span>=</span> <span>ha</span><span>.</span><span>handle</span><span>(</span><span>processedRequest</span><span>,</span> <span>response</span><span>,</span> <span>handlerMethod</span><span>);</span><span>// 3. Render view</span><span>render</span><span>(</span><span>request</span><span>,</span> <span>response</span><span>,</span> <span>mv</span><span>);</span><span>}</span><span>}</span><span>public</span> <span>class</span> <span>DispatcherServlet</span> <span>extends</span> <span>HttpServlet</span> <span>{</span> <span>private</span> <span>WebApplicationContext</span> <span>webApplicationContext</span><span>;</span> <span>private</span> <span>HandlerMapping</span> <span>handlerMapping</span><span>;</span> <span>private</span> <span>HandlerAdapter</span> <span>handlerAdapter</span><span>;</span> <span>private</span> <span>ViewResolver</span> <span>viewResolver</span><span>;</span> <span>@Override</span> <span>public</span> <span>void</span> <span>init</span><span>(</span><span>ServletConfig</span> <span>config</span><span>)</span> <span>throws</span> <span>ServletException</span> <span>{</span> <span>super</span><span>.</span><span>init</span><span>(</span><span>config</span><span>);</span> <span>this</span><span>.</span><span>parentApplicationContext</span> <span>=</span> <span>(</span><span>WebApplicationContext</span><span>)</span> <span>this</span><span>.</span><span>getServletContext</span><span>()</span> <span>.</span><span>getAttribute</span><span>(</span><span>WebApplicationContext</span><span>.</span><span>ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE</span><span>);</span> <span>this</span><span>.</span><span>sContextConfigLocation</span> <span>=</span> <span>config</span><span>.</span><span>getInitParameter</span><span>(</span><span>"contextConfigLocation"</span><span>);</span> <span>this</span><span>.</span><span>webApplicationContext</span> <span>=</span> <span>new</span> <span>AnnotationConfigWebApplicationContext</span><span>(</span> <span>sContextConfigLocation</span><span>,</span> <span>this</span><span>.</span><span>parentApplicationContext</span> <span>);</span> <span>Refresh</span><span>();</span> <span>}</span> <span>protected</span> <span>void</span> <span>doDispatch</span><span>(</span><span>HttpServletRequest</span> <span>request</span><span>,</span> <span>HttpServletResponse</span> <span>response</span><span>)</span> <span>throws</span> <span>Exception</span> <span>{</span> <span>HttpServletRequest</span> <span>processedRequest</span> <span>=</span> <span>request</span><span>;</span> <span>HandlerMethod</span> <span>handlerMethod</span> <span>=</span> <span>null</span><span>;</span> <span>ModelAndView</span> <span>mv</span> <span>=</span> <span>null</span><span>;</span> <span>// 1. Get handler for request</span> <span>handlerMethod</span> <span>=</span> <span>this</span><span>.</span><span>handlerMapping</span><span>.</span><span>getHandler</span><span>(</span><span>processedRequest</span><span>);</span> <span>if</span><span>(</span><span>handlerMethod</span> <span>==</span> <span>null</span><span>)</span> <span>{</span> <span>return</span><span>;</span> <span>}</span> <span>// 2. Execute handler with adapter</span> <span>HandlerAdapter</span> <span>ha</span> <span>=</span> <span>this</span><span>.</span><span>handlerAdapter</span><span>;</span> <span>mv</span> <span>=</span> <span>ha</span><span>.</span><span>handle</span><span>(</span><span>processedRequest</span><span>,</span> <span>response</span><span>,</span> <span>handlerMethod</span><span>);</span> <span>// 3. Render view</span> <span>render</span><span>(</span><span>request</span><span>,</span> <span>response</span><span>,</span> <span>mv</span><span>);</span> <span>}</span> <span>}</span>public class DispatcherServlet extends HttpServlet { private WebApplicationContext webApplicationContext; private HandlerMapping handlerMapping; private HandlerAdapter handlerAdapter; private ViewResolver viewResolver; @Override public void init(ServletConfig config) throws ServletException { super.init(config); this.parentApplicationContext = (WebApplicationContext) this.getServletContext() .getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE); this.sContextConfigLocation = config.getInitParameter("contextConfigLocation"); this.webApplicationContext = new AnnotationConfigWebApplicationContext( sContextConfigLocation, this.parentApplicationContext ); Refresh(); } protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception { HttpServletRequest processedRequest = request; HandlerMethod handlerMethod = null; ModelAndView mv = null; // 1. Get handler for request handlerMethod = this.handlerMapping.getHandler(processedRequest); if(handlerMethod == null) { return; } // 2. Execute handler with adapter HandlerAdapter ha = this.handlerAdapter; mv = ha.handle(processedRequest, response, handlerMethod); // 3. Render view render(request, response, mv); } }
Enter fullscreen mode Exit fullscreen mode
Key features of the Dispatcher:
- Initializes the web application context
- Sets up handler mapping,adapter, and view resolver
- Processes incoming requests through the doDispatch method
- Coordinates between different components of the MVC framework
Request Mapping
The @RequestMapping annotation is used to map web requests to handler methods:
<span>@Target</span><span>(</span><span>value</span> <span>=</span> <span>{</span><span>ElementType</span><span>.</span><span>METHOD</span><span>})</span><span>@Retention</span><span>(</span><span>RetentionPolicy</span><span>.</span><span>RUNTIME</span><span>)</span><span>public</span> <span>@interface</span> <span>RequestMapping</span> <span>{</span><span>String</span> <span>value</span><span>()</span> <span>default</span> <span>""</span><span>;</span><span>}</span><span>@Target</span><span>(</span><span>value</span> <span>=</span> <span>{</span><span>ElementType</span><span>.</span><span>METHOD</span><span>})</span> <span>@Retention</span><span>(</span><span>RetentionPolicy</span><span>.</span><span>RUNTIME</span><span>)</span> <span>public</span> <span>@interface</span> <span>RequestMapping</span> <span>{</span> <span>String</span> <span>value</span><span>()</span> <span>default</span> <span>""</span><span>;</span> <span>}</span>@Target(value = {ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) public @interface RequestMapping { String value() default ""; }
Enter fullscreen mode Exit fullscreen mode
This simple yet powerful annotation allows for:
- Method-level request mapping
- URL pattern matching
- Runtime processing of mapping
Model and View Handling
The ModelAndView class represents both the model data and view information:
<span>public</span> <span>class</span> <span>ModelAndView</span> <span>{</span><span>private</span> <span>Object</span> <span>view</span><span>;</span><span>private</span> <span>Map</span><span><</span><span>String</span><span>,</span> <span>Object</span><span>></span> <span>model</span> <span>=</span> <span>new</span> <span>HashMap</span><span><>();</span><span>public</span> <span>ModelAndView</span><span>(</span><span>String</span> <span>viewName</span><span>,</span> <span>Map</span><span><</span><span>String</span><span>,</span> <span>?></span> <span>modelData</span><span>)</span> <span>{</span><span>this</span><span>.</span><span>view</span> <span>=</span> <span>viewName</span><span>;</span><span>if</span><span>(</span><span>modelData</span> <span>!=</span> <span>null</span><span>)</span> <span>{</span><span>addAllAttributes</span><span>(</span><span>modelData</span><span>);</span><span>}</span><span>}</span><span>public</span> <span>void</span> <span>addAttribute</span><span>(</span><span>String</span> <span>attributeName</span><span>,</span> <span>Object</span> <span>attributeValue</span><span>)</span> <span>{</span><span>model</span><span>.</span><span>put</span><span>(</span><span>attributeName</span><span>,</span> <span>attributeValue</span><span>);</span><span>}</span><span>public</span> <span>ModelAndView</span> <span>addObject</span><span>(</span><span>String</span> <span>attributeName</span><span>,</span> <span>Object</span> <span>attributeValue</span><span>)</span> <span>{</span><span>addAttribute</span><span>(</span><span>attributeName</span><span>,</span> <span>attributeValue</span><span>);</span><span>return</span> <span>this</span><span>;</span><span>}</span><span>// Other methods...</span><span>}</span><span>public</span> <span>class</span> <span>ModelAndView</span> <span>{</span> <span>private</span> <span>Object</span> <span>view</span><span>;</span> <span>private</span> <span>Map</span><span><</span><span>String</span><span>,</span> <span>Object</span><span>></span> <span>model</span> <span>=</span> <span>new</span> <span>HashMap</span><span><>();</span> <span>public</span> <span>ModelAndView</span><span>(</span><span>String</span> <span>viewName</span><span>,</span> <span>Map</span><span><</span><span>String</span><span>,</span> <span>?></span> <span>modelData</span><span>)</span> <span>{</span> <span>this</span><span>.</span><span>view</span> <span>=</span> <span>viewName</span><span>;</span> <span>if</span><span>(</span><span>modelData</span> <span>!=</span> <span>null</span><span>)</span> <span>{</span> <span>addAllAttributes</span><span>(</span><span>modelData</span><span>);</span> <span>}</span> <span>}</span> <span>public</span> <span>void</span> <span>addAttribute</span><span>(</span><span>String</span> <span>attributeName</span><span>,</span> <span>Object</span> <span>attributeValue</span><span>)</span> <span>{</span> <span>model</span><span>.</span><span>put</span><span>(</span><span>attributeName</span><span>,</span> <span>attributeValue</span><span>);</span> <span>}</span> <span>public</span> <span>ModelAndView</span> <span>addObject</span><span>(</span><span>String</span> <span>attributeName</span><span>,</span> <span>Object</span> <span>attributeValue</span><span>)</span> <span>{</span> <span>addAttribute</span><span>(</span><span>attributeName</span><span>,</span> <span>attributeValue</span><span>);</span> <span>return</span> <span>this</span><span>;</span> <span>}</span> <span>// Other methods...</span> <span>}</span>public class ModelAndView { private Object view; private Map<String, Object> model = new HashMap<>(); public ModelAndView(String viewName, Map<String, ?> modelData) { this.view = viewName; if(modelData != null) { addAllAttributes(modelData); } } public void addAttribute(String attributeName, Object attributeValue) { model.put(attributeName, attributeValue); } public ModelAndView addObject(String attributeName, Object attributeValue) { addAttribute(attributeName, attributeValue); return this; } // Other methods... }
Enter fullscreen mode Exit fullscreen mode
This implementation:
- Combines view information with model data
- Provides flexible constructors fro different use cases
- Offers convenient methods for adding attributes
View Resolution
The view resolution process is handled the ViewResolver interface and its implementation:
<span>public</span> <span>interface</span> <span>ViewResolver</span> <span>{</span><span>View</span> <span>resolveViewName</span><span>(</span><span>String</span> <span>viewName</span><span>)</span> <span>throws</span> <span>Exception</span><span>;</span><span>}</span><span>public</span> <span>interface</span> <span>ViewResolver</span> <span>{</span> <span>View</span> <span>resolveViewName</span><span>(</span><span>String</span> <span>viewName</span><span>)</span> <span>throws</span> <span>Exception</span><span>;</span> <span>}</span>public interface ViewResolver { View resolveViewName(String viewName) throws Exception; }
Enter fullscreen mode Exit fullscreen mode
The actual rendering is performed by the View interface:
<span>public</span> <span>interface</span> <span>View</span> <span>{</span><span>void</span> <span>render</span><span>(</span><span>Map</span><span><</span><span>String</span><span>,</span> <span>Object</span><span>></span> <span>model</span><span>,</span> <span>HttpServletRequest</span> <span>request</span><span>,</span><span>HttpServletResponse</span> <span>response</span><span>)</span> <span>throws</span> <span>Exception</span><span>;</span><span>}</span><span>public</span> <span>interface</span> <span>View</span> <span>{</span> <span>void</span> <span>render</span><span>(</span><span>Map</span><span><</span><span>String</span><span>,</span> <span>Object</span><span>></span> <span>model</span><span>,</span> <span>HttpServletRequest</span> <span>request</span><span>,</span> <span>HttpServletResponse</span> <span>response</span><span>)</span> <span>throws</span> <span>Exception</span><span>;</span> <span>}</span>public interface View { void render(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception; }
Enter fullscreen mode Exit fullscreen mode
Request Processing Flow
The request processing flow in miniSpring MVC follows these steps:
- Request Reception
<span>protected</span> <span>void</span> <span>service</span><span>(</span><span>HttpServletRequest</span> <span>request</span><span>,</span> <span>HttpServletResponse</span> <span>response</span><span>)</span> <span>{</span><span>request</span><span>.</span><span>setAttribute</span><span>(</span><span>WEB_APPLICATION_CONTEXT_ATTRIBUTE</span><span>,</span> <span>this</span><span>.</span><span>webApplicationContext</span><span>);</span><span>try</span> <span>{</span><span>doDispatch</span><span>(</span><span>request</span><span>,</span> <span>response</span><span>);</span><span>}</span> <span>catch</span> <span>(</span><span>Exception</span> <span>e</span><span>)</span> <span>{</span><span>throw</span> <span>new</span> <span>RuntimeException</span><span>(</span><span>e</span><span>);</span><span>}</span><span>}</span><span>protected</span> <span>void</span> <span>service</span><span>(</span><span>HttpServletRequest</span> <span>request</span><span>,</span> <span>HttpServletResponse</span> <span>response</span><span>)</span> <span>{</span> <span>request</span><span>.</span><span>setAttribute</span><span>(</span><span>WEB_APPLICATION_CONTEXT_ATTRIBUTE</span><span>,</span> <span>this</span><span>.</span><span>webApplicationContext</span><span>);</span> <span>try</span> <span>{</span> <span>doDispatch</span><span>(</span><span>request</span><span>,</span> <span>response</span><span>);</span> <span>}</span> <span>catch</span> <span>(</span><span>Exception</span> <span>e</span><span>)</span> <span>{</span> <span>throw</span> <span>new</span> <span>RuntimeException</span><span>(</span><span>e</span><span>);</span> <span>}</span> <span>}</span>protected void service(HttpServletRequest request, HttpServletResponse response) { request.setAttribute(WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.webApplicationContext); try { doDispatch(request, response); } catch (Exception e) { throw new RuntimeException(e); } }
Enter fullscreen mode Exit fullscreen mode
- Handler Mapping
<span>handlerMethod</span> <span>=</span> <span>this</span><span>.</span><span>handlerMapping</span><span>.</span><span>getHandler</span><span>(</span><span>processedRequest</span><span>);</span><span>handlerMethod</span> <span>=</span> <span>this</span><span>.</span><span>handlerMapping</span><span>.</span><span>getHandler</span><span>(</span><span>processedRequest</span><span>);</span>handlerMethod = this.handlerMapping.getHandler(processedRequest);
Enter fullscreen mode Exit fullscreen mode
- Handler Execution
<span>mv</span> <span>=</span> <span>ha</span><span>.</span><span>handle</span><span>(</span><span>processedRequest</span><span>,</span> <span>response</span><span>,</span> <span>handlerMethod</span><span>);</span><span>mv</span> <span>=</span> <span>ha</span><span>.</span><span>handle</span><span>(</span><span>processedRequest</span><span>,</span> <span>response</span><span>,</span> <span>handlerMethod</span><span>);</span>mv = ha.handle(processedRequest, response, handlerMethod);
Enter fullscreen mode Exit fullscreen mode
- View Rendering
<span>protected</span> <span>void</span> <span>render</span><span>(</span><span>HttpServletRequest</span> <span>request</span><span>,</span> <span>HttpServletResponse</span> <span>response</span><span>,</span><span>ModelAndView</span> <span>mv</span><span>)</span> <span>throws</span> <span>Exception</span> <span>{</span><span>if</span><span>(</span><span>mv</span> <span>==</span> <span>null</span><span>)</span> <span>{</span><span>response</span><span>.</span><span>getWriter</span><span>().</span><span>flush</span><span>();</span><span>response</span><span>.</span><span>getWriter</span><span>().</span><span>close</span><span>();</span><span>return</span><span>;</span><span>}</span><span>String</span> <span>sTarget</span> <span>=</span> <span>mv</span><span>.</span><span>getViewName</span><span>();</span><span>Map</span><span><</span><span>String</span><span>,</span> <span>Object</span><span>></span> <span>modelMap</span> <span>=</span> <span>mv</span><span>.</span><span>getModel</span><span>();</span><span>View</span> <span>view</span> <span>=</span> <span>resolveViewName</span><span>(</span><span>sTarget</span><span>,</span> <span>modelMap</span><span>,</span> <span>request</span><span>);</span><span>view</span><span>.</span><span>render</span><span>(</span><span>modelMap</span><span>,</span> <span>request</span><span>,</span> <span>response</span><span>);</span><span>}</span><span>protected</span> <span>void</span> <span>render</span><span>(</span><span>HttpServletRequest</span> <span>request</span><span>,</span> <span>HttpServletResponse</span> <span>response</span><span>,</span> <span>ModelAndView</span> <span>mv</span><span>)</span> <span>throws</span> <span>Exception</span> <span>{</span> <span>if</span><span>(</span><span>mv</span> <span>==</span> <span>null</span><span>)</span> <span>{</span> <span>response</span><span>.</span><span>getWriter</span><span>().</span><span>flush</span><span>();</span> <span>response</span><span>.</span><span>getWriter</span><span>().</span><span>close</span><span>();</span> <span>return</span><span>;</span> <span>}</span> <span>String</span> <span>sTarget</span> <span>=</span> <span>mv</span><span>.</span><span>getViewName</span><span>();</span> <span>Map</span><span><</span><span>String</span><span>,</span> <span>Object</span><span>></span> <span>modelMap</span> <span>=</span> <span>mv</span><span>.</span><span>getModel</span><span>();</span> <span>View</span> <span>view</span> <span>=</span> <span>resolveViewName</span><span>(</span><span>sTarget</span><span>,</span> <span>modelMap</span><span>,</span> <span>request</span><span>);</span> <span>view</span><span>.</span><span>render</span><span>(</span><span>modelMap</span><span>,</span> <span>request</span><span>,</span> <span>response</span><span>);</span> <span>}</span>protected void render(HttpServletRequest request, HttpServletResponse response, ModelAndView mv) throws Exception { if(mv == null) { response.getWriter().flush(); response.getWriter().close(); return; } String sTarget = mv.getViewName(); Map<String, Object> modelMap = mv.getModel(); View view = resolveViewName(sTarget, modelMap, request); view.render(modelMap, request, response); }
Enter fullscreen mode Exit fullscreen mode
Integration with IoC Container
The MVC framework integrates with the IoC container through the WebApplicationContext:
<span>protected</span> <span>void</span> <span>initHandlerMappings</span><span>(</span><span>WebApplicationContext</span> <span>wac</span><span>)</span> <span>{</span><span>try</span> <span>{</span><span>this</span><span>.</span><span>handlerMapping</span> <span>=</span> <span>(</span><span>HandlerMapping</span><span>)</span> <span>wac</span><span>.</span><span>getBean</span><span>(</span><span>HANDLER_MAPPING_BEAN_NAME</span><span>);</span><span>}</span> <span>catch</span> <span>(</span><span>BeansException</span> <span>e</span><span>)</span> <span>{</span><span>e</span><span>.</span><span>printStackTrace</span><span>();</span><span>}</span><span>}</span><span>protected</span> <span>void</span> <span>initHandlerMappings</span><span>(</span><span>WebApplicationContext</span> <span>wac</span><span>)</span> <span>{</span> <span>try</span> <span>{</span> <span>this</span><span>.</span><span>handlerMapping</span> <span>=</span> <span>(</span><span>HandlerMapping</span><span>)</span> <span>wac</span><span>.</span><span>getBean</span><span>(</span><span>HANDLER_MAPPING_BEAN_NAME</span><span>);</span> <span>}</span> <span>catch</span> <span>(</span><span>BeansException</span> <span>e</span><span>)</span> <span>{</span> <span>e</span><span>.</span><span>printStackTrace</span><span>();</span> <span>}</span> <span>}</span>protected void initHandlerMappings(WebApplicationContext wac) { try { this.handlerMapping = (HandlerMapping) wac.getBean(HANDLER_MAPPING_BEAN_NAME); } catch (BeansException e) { e.printStackTrace(); } }
Enter fullscreen mode Exit fullscreen mode
This integration provides:
- Automatic bean management
- Dependency injection for controllers
- Configuration management
Example Usage
Here’s how to use the miniSpring MVC framework:
<span>@RequestMapping</span><span>(</span><span>"/hello"</span><span>)</span><span>public</span> <span>ModelAndView</span> <span>handleRequest</span><span>(</span><span>HttpServletRequest</span> <span>request</span><span>)</span> <span>{</span><span>String</span> <span>message</span> <span>=</span> <span>"Hello, World!"</span><span>;</span><span>ModelAndView</span> <span>mv</span> <span>=</span> <span>new</span> <span>ModelAndView</span><span>(</span><span>"hello"</span><span>);</span><span>mv</span><span>.</span><span>addObject</span><span>(</span><span>"message"</span><span>,</span> <span>message</span><span>);</span><span>return</span> <span>mv</span><span>;</span><span>}</span><span>@RequestMapping</span><span>(</span><span>"/hello"</span><span>)</span> <span>public</span> <span>ModelAndView</span> <span>handleRequest</span><span>(</span><span>HttpServletRequest</span> <span>request</span><span>)</span> <span>{</span> <span>String</span> <span>message</span> <span>=</span> <span>"Hello, World!"</span><span>;</span> <span>ModelAndView</span> <span>mv</span> <span>=</span> <span>new</span> <span>ModelAndView</span><span>(</span><span>"hello"</span><span>);</span> <span>mv</span><span>.</span><span>addObject</span><span>(</span><span>"message"</span><span>,</span> <span>message</span><span>);</span> <span>return</span> <span>mv</span><span>;</span> <span>}</span>@RequestMapping("/hello") public ModelAndView handleRequest(HttpServletRequest request) { String message = "Hello, World!"; ModelAndView mv = new ModelAndView("hello"); mv.addObject("message", message); return mv; }
Enter fullscreen mode Exit fullscreen mode
And the corresponding configuration:
<span><bean</span> <span>class=</span><span>"com.yaruyng.web.servlet.SimpleUrlHandlerMapping"</span><span>></span><span><property</span> <span>name=</span><span>"mappings"</span><span>></span><span><props></span><span><prop</span> <span>key=</span><span>"/hello"</span><span>></span>helloController<span></prop></span><span></props></span><span></property></span><span></bean></span><span><bean</span> <span>class=</span><span>"com.yaruyng.web.servlet.SimpleUrlHandlerMapping"</span><span>></span> <span><property</span> <span>name=</span><span>"mappings"</span><span>></span> <span><props></span> <span><prop</span> <span>key=</span><span>"/hello"</span><span>></span>helloController<span></prop></span> <span></props></span> <span></property></span> <span></bean></span><bean class="com.yaruyng.web.servlet.SimpleUrlHandlerMapping"> <property name="mappings"> <props> <prop key="/hello">helloController</prop> </props> </property> </bean>
Enter fullscreen mode Exit fullscreen mode
Performance Considerations
The implementation includes several performance optimizations:
- Single Front Controller: All request go through a single servlet
- Handler Caching: Handler methods are cached after first resolution
- View Caching: Resolved views are cached for reuse
- Efficient Request Processing: Minimal object creation per request
Extension Points
The framework provides several extension points:
- Custom Handler Mappings: Implement HandlerMapping interface
- Custom View Resolvers: Implement ViewResolver interface
- Custom Handler Adapters: Implement HandlerAdapter interface
- Custom Views: Implement View interface
Conclusion
This implementation of Spring MVC demonstrates:
- The power of the front controller pattern
- Clean separation of concerns through MVC
- Flexible handling of requests and responses
- Integration with IoC container
- Extensible architecture Key takeaways:
- Understanding Spring MVC’s internal structure
- How different components work together
- The importance of clean architecture
- Extension points for customization
The miniSpring MVC implementation provides a solid foundation for understanding how Spring MVC works internally while maintaining simplicity and clarity.
原文链接:Spring Architecture Series-3.Understanding Spring MVC Implementation
暂无评论内容