精华内容
下载资源
问答
  • SpringMVC实现原理及方法
    2019-03-22 11:01:08

    SpringMVC原理
    M => Model 模型 响应请求并返回相关数据
    V =》View视图 对数据进行视图渲染
    C =》controller 控制器 监听用户的请求以及最终响应用户
    在这里插入图片描述
    处理流程:
    1.url /login =》DispatcherServlet(/和/*) @Controller @RequestMapping DispatcherServlet的doDispatcher()

    2.DispatcherServlet通过寻找合适的HandlerMapping,返回Handler和拦截器 prehandler postHandler AfterCompletion

    3.DispatcherServlet通过合适的HandlerAdapter来执行上面的handler,把请求交给最终的action方法并执行,并在方法执行的前后,执行上面第2步返回的拦截器的方法。handler执行完,最终会返回Model and View

    如果action方法定义了@ResponseBody,那么使用Spring MVC内置的Jackson把返回值封装成json字符串,跳到第6步

    4.DispatcherServlet根据配置好的试图解析器InternalResourceViewReslover来找到具体的视图文件 hello /web-inf/jsp/hello.jsp

    5.Tomcat(*.jsp)会把modal里面的数据渲染到上面的视图文件当中

    6.Tomcat把上面的最终渲染好的视图文件返回给客户端response

    MVC实现流程及方法
    preHandle():在请求处理之前被调用,用来判断请求是否继续执行。
    postHandle():在请求处理之后调用,可以对Controller 处理之后的ModelAndView 对象进行操作
    afterCompletion():在整个请求处理结束之后执行。用于进行资源清理工作的。

    更多相关内容
  • SpringMVC实现原理

    千次阅读 2017-09-27 20:23:27
    今天我们来实现一个简单的springMVC框架,可以理解为 springMVC1.0这个版本,只是功能比较简单而已;废话不多说,进入正题;先看看springMVC的简单流程;我们请求的地址会被dispatchservlet这个springMVC的核心拦截...

    今天我们来实现一个简单的springMVC框架,可以理解为 springMVC1.0这个版本,只是功能比较简单而已;

    废话不多说,进入正题;先看看springMVC的简单流程;


    我们请求的地址会被dispatchservlet这个springMVC的核心拦截器拦截,然后dispatchservlet会找到我们想要的那个controller里的那个方法,并调用。但是dispatchServlet不是人,它没那么智能,看到url就知道是谁了,但是我们可以让它变得智能起来,我们可以利用handlerMapping来告诉

    dispatchServlet,它应该调用哪个方法;

    为了让这个框架不那么笨,我借用了spring的IOC 思想, 实现一个容器来管理我的bean; 这个框架和你印象中使用springmvc 很相似,你应该能回想起

    springMVC的零零点点,然后看看这个简单的框架是如何实现这些功能的;

    首先看下项目工程:


    首先,我们先看maven 依赖,没错,自己实现的框架当然不用spring的jar包了;

    并为了方便大家理解,我的取名和spring原来的风格多少有些类似;

    首先看到annotation包,@Autowired、@Controller、@RequestMapping、@service这些注解大家应该再熟悉不过了吧!

    然后是 servlet包,模仿的springMVC的核心拦截器 dispatchServlet;

    demo包的 controller service  不必解释啦~


    这里我们模仿springMVC的调用规则,MyDispatcherServlet负责处理框架的逻辑,调用Controller,Controller调用service;

    先看看自定义注解是如何定义的,这里挑选了几个代表;





    开始编写核心拦截器 dispatchServilet


    我们第一步模仿spring 的思想,先找到我们要扫描哪些类,下面是 spring的做法,



    这是我的做法:


    为什么我通过  String scanPackage = config.getInitParameter("scanPackage"); 就能找到xml中的配置呢?请参考这里 的初始化细节;

    servlet 对象在初始化的时候,容器会给它提供一个 ServletConfig 对象  去读取 web.xml中的配置;


    我们得到要扫描的路径后,可以就需要实现spring的IOC了;

    我们为了得到所有bean;在拿到项目的包路径后,可以转换为文件路径,然后再从文件路径中得到所有的类名;

    得到类名后,就可以通过反射进行实例化了,然后将这些需要管理的东西放到一个容器中管理,要用的时候从容器里拿就可以了;

    我这里使用的容器是 Hashmap<String, Object>    类的简称(SimpleName)为key ,类的实例对象为value。


    得到了所有的类名后,开始实例化的工作

    private void instance(){
    		//利用反射机制将扫描到的类名全部实例化
    		if(classNames.size() == 0){ return; }
    		try{
    			for (String className : classNames) {
    				
    					Class<?> clazz = Class.forName(className);
    					//没有@Controller、@Service注解标识的类不需要实例化
    					if(clazz.isAnnotationPresent(LANController.class)){
    						//getSimpleName() 除去包名,获取类名的简称  例如: MyAction
    						String beanName = lowerFirstChar(clazz.getSimpleName());
    						instanceMapping.put(beanName, clazz.newInstance());
    					}else if(clazz.isAnnotationPresent(LANService.class)){
    						LANService service = clazz.getAnnotation(LANService.class);
    						String beanName = service.value();
    						if(!"".equals(beanName.trim())){
    							//beanName 这里就是aa
    							instanceMapping.put(beanName, clazz.newInstance());
    							continue;
    						}
    						//如果自己没有起名字,后面会通过接口自动注入
    						Class<?> [] interfaces = clazz.getInterfaces();
    						for (Class<?> i : interfaces) {
    							instanceMapping.put(i.getName(), clazz.newInstance());
    						}
    					}else{
    						continue;
    					}
    			}
    		}catch(Exception e){
    			e.getStackTrace();
    		}
    	}

    实例化以后,就要准备注入了;

    private void autowired(){
    		if(instanceMapping.isEmpty()){ return; }
    		for (Entry<String, Object> entry : instanceMapping.entrySet()) {
    			//getDeclaredFields()获取自己声明的所有字段
    			Field [] fields = entry.getValue().getClass().getDeclaredFields();
    			for (Field field : fields) {
    				if(!field.isAnnotationPresent(LANAutowired.class)){ continue; }
    				LANAutowired autowired = field.getAnnotation(LANAutowired.class);
    				//如果是私有属性,设置可以访问的权限
    				field.setAccessible(true);
    				//自己取的名字   获取注解的值
    				String beanName = autowired.value().trim();
    				System.out.println("beanName=="+beanName);
    				//如果没有自己取名字
    				if("".equals(beanName)){
    					//getType()获取该字段声明时的     类型对象   根据类型注入
    					beanName = field.getType().getName();
    				}
    				try {
    					System.out.println("field.getName()***"+field.getName());
    					 // 注入接口的实现类,  
    					 System.out.println("entry.getValue()======"+entry.getValue());
    					 System.out.println("instanceMapping.get(beanName)---------"+instanceMapping.get(beanName));
    					 //将Action 这个 类的 IModifyService 字段设置成为   aa 代表的实现类  ModifyServiceImpl
    					field.set(entry.getValue(),instanceMapping.get(beanName));
    				} catch (Exception e) {
    					e.printStackTrace();
    					continue;
    				}
    			}
    		}
    	}


    field.set(entry.getValue(),instanceMapping.get(beanName));
    这一行代码是关键,这就是为什么我们在注入接口,就能找到实现类的根本所在。

    这里的field,就是我们注入的那个接口, entry.getValue() 得到的是接口所在的类,instanceMapping.get(beanName)是这个接口对应的

    那个实现类,   意思就是:在 运行阶段, 将 controller中 的某个service接口字段 替换成 这个service的实现类;

    这样我们在编写代码的时候是用使用接口调用方法,但实际运行时,就是它的实现类在调用这个方法了;

    不得不感叹,反射的强大。


    完成注入后,开始处理handlermapping上的value与之对应的method 的映射关系了

    public void handlerMapping(){
    		if(instanceMapping.isEmpty()){ return; }
    		for (Entry<String, Object> entry : instanceMapping.entrySet()) {
    			Class<?> clazz = entry.getValue().getClass();
    			//RequestMapping只在 Controller中
    			if(!clazz.isAnnotationPresent(LANController.class)){ continue; }
    			String url = "";
    			if(clazz.isAnnotationPresent(LANRequestMapping.class)){
    				LANRequestMapping requstMapping = clazz.getAnnotation(LANRequestMapping.class);
    				//得到RequstMapping的value(/web)准备与 方法上的 RequstMapping(search/add/remove)进行拼接;
    				url = requstMapping.value();//(/web)
    			}
    			Method [] methods = clazz.getMethods();
    			for (Method method : methods) {
    				if(!method.isAnnotationPresent(LANRequestMapping.class)){ continue; }
    				LANRequestMapping requstMapping = method.getAnnotation(LANRequestMapping.class);
    				String regex =  url + requstMapping.value();
    			 // regex = /web/add.json
    				regex = regex.replaceAll("/+", "/").replaceAll("\\*", ".*");
    				System.out.println("regex: "+regex);
    				Map<String,Integer> pm = new HashMap<String,Integer>();
    				//因为每个参数可能有多个注解,所以会是个二维数组
    				Annotation [] [] pa = method.getParameterAnnotations();
    				for(int i = 0; i < pa.length; i ++){
    					for (Annotation a : pa[i]){
    						if(a instanceof LANRequestParam){
    							String paramName = ((LANRequestParam) a).value();
    							if(!"".equals(paramName.trim())){
    					  //方法参数的名字(值)  name/addr,下标
    								pm.put(paramName, i);
    							}
    						}
    					}
    				}
    				//提取Request和Response的索引
    				Class<?> [] paramsTypes = method.getParameterTypes();
    				for(int i = 0 ; i < paramsTypes.length; i ++){
    					Class<?> type = paramsTypes[i];
    					if(type == HttpServletRequest.class ||  type == HttpServletResponse.class){
    						
    						pm.put(type.getName(), i);
    					}
    				}
    				handlerMapping.add(new Handler(Pattern.compile(regex),entry.getValue(),method, pm));
    			}
    		}
    	}

    完成所有的初始化工作后,当然就等着用户发过来的请求咯。

    那自然是调用servlet的 doPost 和 doGet方法了,

    为了简单点,我在doGet中调用doPost

    @Override
    	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    		this.doPost(req, resp);
    	}
    
    	@Override
    	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    		//System.out.println(req.getRequestURI());
    		try{
    			//从上面已经初始化的信息中匹配
    			//拿着用户请求url去找到其对应的Method
    			boolean isMatcher = pattern(req,resp);
    		if(!isMatcher){
    			resp.getWriter().write("对不起,你遇到了  404 Not Found");
    		}
    		}catch(Exception e){
    			resp.getWriter().write("500 Exception,Details:\r\n" + 
    			e.getMessage() + "\r\n" +
    			Arrays.toString(e.getStackTrace()).replaceAll("\\[\\]", "")
    			.replaceAll(",\\s", "\r\n"));
    		}
    	}
    如果如果没有匹配成功就返回404,说明用户的路径输错了,

    发送异常就报500;

    如果匹配成功怎么办? 当然是调用controller里的方法咯;

    怎么调用?还是通过反射~通过方法的反射~

    public boolean pattern(HttpServletRequest req, HttpServletResponse resp) throws Exception{
    		if(handlerMapping.isEmpty()){  return false; }
    		//获取请求的url
    		String url = req.getRequestURI();
    		//获取容器路径
    		String contextPath = req.getContextPath();
    		url = url.replace(contextPath, "").replaceAll("/+", "/");	
    		for (Handler handler : handlerMapping) {
    			try{
    				Matcher matcher = handler.pattern.matcher(url);
    				//如果没匹配上就跳出
    				if(!matcher.matches()){ continue ;}
    				//按照声明顺序返回  Class 对象的数组,这些对象描述了此 Method 对象所表示的方法的形参类型。
    				Class<?> [] paramTypes = handler.method.getParameterTypes();
    				//里面存放 反射是需要的具体参数
    				Object [] paramValues = new Object[paramTypes.length];
    				//获取前端请求参数和请求参数值的映射关系
    				Map<String,String[]> params = req.getParameterMap();
    				for (Entry<String, String []> param : params.entrySet()) {
    					String value = Arrays.toString(param.getValue()).replaceAll("\\]|\\[", "").replaceAll(",\\s", ",");
    					if(!handler.paramMapping.containsKey(param.getKey())){ continue;}
    					//如果匹配,则获取该参数在方法中的下标;
    					int index = handler.paramMapping.get(param.getKey());
    					//涉及到类型转换
    					paramValues[index] = castStringValue(value,paramTypes[index]);
    				}
    				//
    				int reqIndex = handler.paramMapping.get(HttpServletRequest.class.getName());
    				paramValues[reqIndex] = req;
    				int respIndex = handler.paramMapping.get(HttpServletResponse.class.getName());
    				paramValues[respIndex] = resp;
    				//方法的反射   需要对象.方法
    				handler.method.invoke(handler.controller, paramValues);
    				return true;
    			}catch(Exception e){
    				throw e;
    			}
    		}
    		return false;
    	}


    我们来看看controller的代码,准备测试:

    public class MyController {
    	
    	public  MyController() {
    		System.out.println("初始化了"+this);
    	}
    	
    	@LANAutowired 
    	private searchService searchService;
    	
    	@LANAutowired("aa") 
    	private modifyService modifyService;
    	
    	@LANRequestMapping("/search/*.json")
    	public void search(HttpServletRequest request,HttpServletResponse response,
    			@LANRequestParam("name") String name){
    		String result = searchService.search(name);
    		System.out.println("查询成功");
    		out(response,result);
    	}
    	
    	
    	@LANRequestMapping("/add.json")
    	public void add(HttpServletRequest request,HttpServletResponse response,
    			@LANRequestParam("name") String name,
    			@LANRequestParam("addr") String addr){
    		System.out.println("添加成功");
    		String result = modifyService.add(name,addr);
    		out(response,result);
    	}
    	
    	
    	@LANRequestMapping("/delete.json")
    	public void remove(HttpServletRequest request,HttpServletResponse response,
    			@LANRequestParam("id") Integer id){
    		System.out.println("删除成功");
    		String result = modifyService.remove(id);
    		out(response,result);
    	}
    是不是和你刚学springMVC时的一致?

    赶紧启动项目在地址栏输入:http://localhost:8080/LanSpringMVC/web/add.json?name=witt&addr=shenzhen

    出现:

    add name = witt,addr=shenzhen
    说明大工告成~

    想要源码的小伙伴点这里:源码


    展开全文
  • SpringMVC实现原理及详解

    万次阅读 多人点赞 2018-05-24 11:16:14
    3、SpringMVC运行原理 如图所示: 流程说明: (1)客户端(浏览器)发送请求,直接请求到DispatcherServlet。 (2) DispatcherServlet 根据请求信息调用HandlerMapping,解析请求对应的Handler。 (3)解析到对应...

    1、Spring mvc介绍

    SpringMVC框架是以请求为驱动,围绕Servlet设计,将请求发给控制器,然后通过模型对象,分派器来展示请求结果视图。其中核心类是DispatcherServlet,它是一个Servlet,顶层是实现的Servlet接口。


    2、SpringMVC使用

    需要在web.xml中配置DispatcherServlet。并且需要配置spring监听器ContextLoaderListener

            <listener>
                <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
            </listener>        
            <servlet>
    		<servlet-name>springmvc</servlet-name>
    		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
                    <!-- 如果不设置init-param标签,则必须在/WEB-INF/下创建xxx-servlet.xml文件,其中xxx是servlet-name中配置的名称。  -->
                    <init-param>
    			<param-name>contextConfigLocation</param-name>
    			<param-value>classpath:spring/springmvc-servlet.xml</param-value>
    		</init-param>
    		<load-on-startup>1</load-on-startup>
    	</servlet>
    	<servlet-mapping>
    		<servlet-name>springmvc</servlet-name>
    		<url-pattern>/</url-pattern>
    	</servlet-mapping>

    3、SpringMVC运行原理

    如图所示:


    流程说明:

    (1)客户端(浏览器)发送请求,直接请求到DispatcherServlet。

    (2)DispatcherServlet根据请求信息调用HandlerMapping,解析请求对应的Handler。

    (3)解析到对应的Handler后,开始由HandlerAdapter适配器处理。

    (4)HandlerAdapter会根据Handler来调用真正的处理器开处理请求,并处理相应的业务逻辑。

    (5)处理器处理完业务后,会返回一个ModelAndView对象,Model是返回的数据对象,View是个逻辑上的View。

    (6)ViewResolver会根据逻辑View查找实际的View。

    (7)DispaterServlet把返回的Model传给View。

    (8)通过View返回给请求者(浏览器)

    4、DispatcherServlet详细解析

    首先看下源码:

    package org.springframework.web.servlet;
    
    @SuppressWarnings("serial")
    public class DispatcherServlet extends FrameworkServlet {
    
    	public static final String MULTIPART_RESOLVER_BEAN_NAME = "multipartResolver";
    	public static final String LOCALE_RESOLVER_BEAN_NAME = "localeResolver";
    	public static final String THEME_RESOLVER_BEAN_NAME = "themeResolver";
    	public static final String HANDLER_MAPPING_BEAN_NAME = "handlerMapping";
    	public static final String HANDLER_ADAPTER_BEAN_NAME = "handlerAdapter";
    	public static final String HANDLER_EXCEPTION_RESOLVER_BEAN_NAME = "handlerExceptionResolver";
    	public static final String REQUEST_TO_VIEW_NAME_TRANSLATOR_BEAN_NAME = "viewNameTranslator";
    	public static final String VIEW_RESOLVER_BEAN_NAME = "viewResolver";
    	public static final String FLASH_MAP_MANAGER_BEAN_NAME = "flashMapManager";
    	public static final String WEB_APPLICATION_CONTEXT_ATTRIBUTE = DispatcherServlet.class.getName() + ".CONTEXT";
    	public static final String LOCALE_RESOLVER_ATTRIBUTE = DispatcherServlet.class.getName() + ".LOCALE_RESOLVER";
    	public static final String THEME_RESOLVER_ATTRIBUTE = DispatcherServlet.class.getName() + ".THEME_RESOLVER";
    	public static final String THEME_SOURCE_ATTRIBUTE = DispatcherServlet.class.getName() + ".THEME_SOURCE";
    	public static final String INPUT_FLASH_MAP_ATTRIBUTE = DispatcherServlet.class.getName() + ".INPUT_FLASH_MAP";
    	public static final String OUTPUT_FLASH_MAP_ATTRIBUTE = DispatcherServlet.class.getName() + ".OUTPUT_FLASH_MAP";
    	public static final String FLASH_MAP_MANAGER_ATTRIBUTE = DispatcherServlet.class.getName() + ".FLASH_MAP_MANAGER";
    	public static final String EXCEPTION_ATTRIBUTE = DispatcherServlet.class.getName() + ".EXCEPTION";
    	public static final String PAGE_NOT_FOUND_LOG_CATEGORY = "org.springframework.web.servlet.PageNotFound";
    	private static final String DEFAULT_STRATEGIES_PATH = "DispatcherServlet.properties";
    	protected static final Log pageNotFoundLogger = LogFactory.getLog(PAGE_NOT_FOUND_LOG_CATEGORY);
    	private static final Properties defaultStrategies;
    	static {
    		try {
    			ClassPathResource resource = new ClassPathResource(DEFAULT_STRATEGIES_PATH, DispatcherServlet.class);
    			defaultStrategies = PropertiesLoaderUtils.loadProperties(resource);
    		}
    		catch (IOException ex) {
    			throw new IllegalStateException("Could not load 'DispatcherServlet.properties': " + ex.getMessage());
    		}
    	}
    
    	/** Detect all HandlerMappings or just expect "handlerMapping" bean? */
    	private boolean detectAllHandlerMappings = true;
    
    	/** Detect all HandlerAdapters or just expect "handlerAdapter" bean? */
    	private boolean detectAllHandlerAdapters = true;
    
    	/** Detect all HandlerExceptionResolvers or just expect "handlerExceptionResolver" bean? */
    	private boolean detectAllHandlerExceptionResolvers = true;
    
    	/** Detect all ViewResolvers or just expect "viewResolver" bean? */
    	private boolean detectAllViewResolvers = true;
    
    	/** Throw a NoHandlerFoundException if no Handler was found to process this request? **/
    	private boolean throwExceptionIfNoHandlerFound = false;
    
    	/** Perform cleanup of request attributes after include request? */
    	private boolean cleanupAfterInclude = true;
    
    	/** MultipartResolver used by this servlet */
    	private MultipartResolver multipartResolver;
    
    	/** LocaleResolver used by this servlet */
    	private LocaleResolver localeResolver;
    
    	/** ThemeResolver used by this servlet */
    	private ThemeResolver themeResolver;
    
    	/** List of HandlerMappings used by this servlet */
    	private List<HandlerMapping> handlerMappings;
    
    	/** List of HandlerAdapters used by this servlet */
    	private List<HandlerAdapter> handlerAdapters;
    
    	/** List of HandlerExceptionResolvers used by this servlet */
    	private List<HandlerExceptionResolver> handlerExceptionResolvers;
    
    	/** RequestToViewNameTranslator used by this servlet */
    	private RequestToViewNameTranslator viewNameTranslator;
    
    	private FlashMapManager flashMapManager;
    
    	/** List of ViewResolvers used by this servlet */
    	private List<ViewResolver> viewResolvers;
    
    	public DispatcherServlet() {
    		super();
    	}
    
    	public DispatcherServlet(WebApplicationContext webApplicationContext) {
    		super(webApplicationContext);
    	}
    
    	@Override
    	protected void onRefresh(ApplicationContext context) {
    		initStrategies(context);
    	}
    
    	protected void initStrategies(ApplicationContext context) {
    		initMultipartResolver(context);
    		initLocaleResolver(context);
    		initThemeResolver(context);
    		initHandlerMappings(context);
    		initHandlerAdapters(context);
    		initHandlerExceptionResolvers(context);
    		initRequestToViewNameTranslator(context);
    		initViewResolvers(context);
    		initFlashMapManager(context);
    	}
    }
    

    DispatcherServlet类中的属性beans:

    HandlerMapping:用于handlers映射请求和一系列的对于拦截器的前处理和后处理,大部分用@Controller注解。

    HandlerAdapter:帮助DispatcherServlet处理映射请求处理程序的适配器,而不用考虑实际调用的是 哪个处理程序。

    HandlerExceptionResolver:处理映射异常。

    ViewResolver:根据实际配置解析实际的View类型。

    LocaleResolver:解决客户正在使用的区域设置以及可能的时区,以便能够提供国际化视野。

    ThemeResolver:解决Web应用程序可以使用的主题,例如提供个性化布局。

    MultipartResolver:解析多部分请求,以支持从HTML表单上传文件。

    FlashMapManager:存储并检索可用于将一个请求属性传递到另一个请求的input和output的FlashMap,通常用于重定向。

    在Web MVC框架中,每个DispatcherServlet都拥自己的WebApplicationContext,它继承了ApplicationContext。WebApplicationContext包含了其上下文和Servlet实例之间共享的所有的基础框架beans。


    • HandlerMapping:


    HandlerMapping接口处理请求的映射

    HandlerMapping接口的实现类:

    SimpleUrlHandlerMapping类通过配置文件把URL映射到Controller类。

    DefaultAnnotationHandlerMapping类通过注解把URL映射到Controller类。


    • HandlerAdapter:


    HandlerAdapter接口-处理请求映射

    AnnotationMethodHandlerAdapter:通过注解,把请求URL映射到Controller类的方法上。

    • HandlerExceptionResolver


    HandlerExceptionResolver接口-异常处理接口

    SimpleMappingExceptionResolver通过配置文件进行异常处理。

    AnnotationMethodHandlerExceptionResolver:通过注解进行异常处理。

    • ViewResolver:

    ViewResolver接口解析View视图。

    UrlBasedViewResolver类 通过配置文件,把一个视图名交给到一个View来处理。


    参考资料:http://elf8848.iteye.com/blog/875830

    展开全文
  • SpringMVC的原理如下图所示: 当用户发起请求时,前置的控制器拦截到该请求...上图为SpringMVC实现原理流程图,图中实线部分为SpringMVC框架提供的技术,不需要开发者实现,而虚线部分为开发者需要实现的部分。 ...

    SpringMVC的原理如下图所示:

     

            当用户发起请求时,前置的控制器拦截到该请求,根据请求参数生成代理请求,找到对应的实际控制器,控制器处理请求,创建数据模型,访问数据库,将模型响应给中心控制器,控制器使用模型与视图渲染视图结果,将结果返回给中心控制器,最后返回给用户。

    SpringMVC实现原理

            上图为SpringMVC实现原理流程图,图中实线部分为SpringMVC框架提供的技术,不需要开发者实现,而虚线部分为开发者需要实现的部分。

    执行流程分析

    1.DispatcherServlet表示前置控制器,是整个SpringMVC的控制中心,用户发出请求,DispatcherServlet接收请求并拦截;

    • 假设收到的请求为:http://localhost:8080/SpringMVC/hello
    • http://localhost:8080表示服务器域名
    • SpringMVC表示部署在服务器上的web站点
    • hello表示控制器
    • 通过分析,上述url表示为:请求位于服务器http://localhost上的SpringMVC站点的hello控制.

     2.HandlerMapping为处理器映射。由DispatcherServlet,HandlerMapping根据url查找handler(控制器)

    3.HandlerExecution表示具体的Handler,主要作用是根据url查找控制器,如上的url被查找控制器为:hello

    4.HandlerExecution将解析后的信息传递给DispatcherServlet,如解析控制器映射等

    5.HandlerAdapter表示处理器适配器,按照特定的规则去执行Handler

    6.Handler让具体的Controller执行

    7.Controller将具体的执行信息返回给HandlerAdapter

    8.HandlerAdapter将视图逻辑名或模型传递给DispatcherServlet

    9.DispatcherServlet调用试图解析器解析HandlerAdapter传递过来的视图名

    10.视图解析器将解析的逻辑视图名传给DispatcherServlet

    11.DispatcherServlet根据视图解析器解析的视图结果,调用具体视图

    12.将视图呈现给用户

    简言之,SpringMVC的执行流程可以分为三个阶段:

    1. 根据用户请求找到对应的映射器,并返回;

    2. 再根据此映射器去适配此映射器(有controller执行),并返回一个modelandview;

    3.通过modelandview调用视图解析器,返回给前端用户。

    展开全文
  • amp;utm_campaign=client_share&amp;app=explore_article&amp;utm_source=mobile_qq&amp;iid=5840657922&amp;utm_medium=toutiao_ios   其他: https:...
  • 关于SpringMVC实现原理先总的阐述如下: 当用户端发起请求时,这时前端控制器(可简单理解为DispatchServlet[在web.xml中设置])拦截到请求,根据请求参数(主要是URL)生成代理请求,找到请求对应的实际控制器...
  • spring mvc的入口是servlet,而struts2是filter,这样就导致了二者的机制不同。 spring mvc是基于方法的设计,sturts2是基于类设计的。 springmvc将url和controller方法映射。...springmvc的controller开发类似s...
  • SpringMvc实现原理

    千次阅读 2016-01-31 20:21:25
    最近一直在学习SpringMvc,来总结下SpringMvc到底是什么? 什么是MVC——Model-View-Control  框架性质的C 层要完成的主要工作:封装web 请求为一个数据对象、调用业务逻辑层来处理数据对象、 返回处理数据结果...
  • 文章目录SpringMVC——SpringMVC实现和工作原理详解1、回顾MVC1.1 Model1和Model22、回顾Servlet3、什么是SpringMVC4、HelloSpringMVC5、SpringMVC的工作原理6、注解版实现SpringMVC SpringMVC——SpringMVC实现...
  • 主要介绍了SpringMVC文件上传原理实现过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
  • SpringMVC基本原理详解

    2020-03-20 09:45:58
    MVC是什么、SpringMVC是什么、能帮我们做什么? 带着问题去学习: SpringMVC是帮助我们开发Web项目的,下面讲简单分析, 我们为要用到SpringMVC?以及 MVC是什么?SpringMVC是什么?能帮我们做什么? 1、最初的web ...
  • SpringMvc工作原理学习总结

    万次阅读 多人点赞 2020-11-07 10:42:47
    SpringMvc工作原理 了解SpringMvc之前先看看Mvc的工作原理 1、MVC工作原理 M:Model(完成业务逻辑 Service/dao/entity/) V:View(完成界面渲染 jsp/html) C:Controller(控制器->类似于CPU 接受请求->调用M...
  • SpringMVC实现原理及详解 Spring MVC框架简介 Spring MVC是什么呢?它是属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面。 Spring的MVC框架主要由DispatcherServlet、处理器映射器、处理器(控制器)、...
  • 一个类需要用到某个接口的方法,我们需要将类A和接口B的实现关联起来,最简单的方法是类A中创建一个对于接口B的实现C的实例,但这种方法显然两者的依赖(Dependency)太大了。而IoC的方法是只在类A中定义好用于关联...
  • SpringMVC工作原理

    万次阅读 2018-09-18 08:52:06
    一、首先,我们先来认识一下SpringMVC的主要组件 前端控制器(DisatcherServlet):接收请求,响应结果,返回可以是json,String等数据类型,也可以是页面(Model)。 处理器映射器(HandlerMapping):根据URL去查找...
  • public String getStaticPathPattern() { return this.staticPathPattern; }
  • SpringMvc运行原理

    2019-10-06 19:58:17
    原理: 1.客户端请求提交到DispatcherServlet; 2.由DispatcherServlet控制器查询一个或多个HandlerMapping,找到处理请求的Controller; 3.DispatcherServlet将请求提交到Controller; 4.Controller调用业务逻辑...
  • 1、Spring mvc介绍 ...其中核心类是DispatcherServlet,它是一个Servlet,顶层是实现的Servlet接口。 2、SpringMVC使用 需要在web.xml中配置DispatcherServlet。并且需要配置spring监听器Context...
  • SpringMVC工作原理概述

    万次阅读 多人点赞 2019-01-24 16:04:55
    SpringMVC框架介绍 Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面。 Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块。使用 Spring 可插入的 MVC 架构,可以选择是使用内置的 ...
  • **springmvc 搭建以及基本原理**springmvc基本介绍springmvc工作原理配置文件web.xml配置文件springmvc.xml配置文件Controller springmvc基本介绍 springmvc 是在spring上开发的一套mvc框架。mvc是什么? mvc 就是...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 47,634
精华内容 19,053
关键字:

springmvc实现原理

spring 订阅