Spring 关键点

来源:互联网 发布:windows文件共享端口 编辑:程序博客网 时间:2024/05/22 10:58

1. 拦截器

Spring MVC Interceptor, Spring Interceptor example, Spring interceptor



package com.journaldev.spring;import java.text.DateFormat;import java.util.Date;import java.util.Locale;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.stereotype.Controller;import org.springframework.ui.Model;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;/** * Handles requests for the application home page. */@Controllerpublic class HomeController {private static final Logger logger = LoggerFactory.getLogger(HomeController.class);@RequestMapping(value = "/home", method = RequestMethod.GET)public String home(Locale locale, Model model) {logger.info("Welcome home! The client locale is {}.", locale);//adding some time lag to check interceptor executiontry {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}Date date = new Date();DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);String formattedDate = dateFormat.format(date);model.addAttribute("serverTime", formattedDate );logger.info("Before returning view page");return "home";}}



package com.journaldev.spring;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.web.servlet.ModelAndView;import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;public class RequestProcessingTimeInterceptor extends HandlerInterceptorAdapter {private static final Logger logger = LoggerFactory.getLogger(RequestProcessingTimeInterceptor.class);@Overridepublic boolean preHandle(HttpServletRequest request,HttpServletResponse response, Object handler) throws Exception {long startTime = System.currentTimeMillis();logger.info("Request URL::" + request.getRequestURL().toString()+ ":: Start Time=" + System.currentTimeMillis());request.setAttribute("startTime", startTime);//if returned false, we need to make sure 'response' is sentreturn true;}@Overridepublic void postHandle(HttpServletRequest request,HttpServletResponse response, Object handler,ModelAndView modelAndView) throws Exception {System.out.println("Request URL::" + request.getRequestURL().toString()+ " Sent to Handler :: Current Time=" + System.currentTimeMillis());//we can add attributes in the modelAndView and use that in the view page}@Overridepublic void afterCompletion(HttpServletRequest request,HttpServletResponse response, Object handler, Exception ex)throws Exception {long startTime = (Long) request.getAttribute("startTime");logger.info("Request URL::" + request.getRequestURL().toString()+ ":: End Time=" + System.currentTimeMillis());logger.info("Request URL::" + request.getRequestURL().toString()+ ":: Time Taken=" + (System.currentTimeMillis() - startTime));}}

<?xml version="1.0" encoding="UTF-8"?>

<beans:beans xmlns="http://www.springframework.org/schema/mvc"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsdhttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure --><!-- Enables the Spring MVC @Controller programming model --><annotation-driven /><!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory --><resources mapping="/resources/**" location="/resources/" /><!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory --><beans:beanclass="org.springframework.web.servlet.view.InternalResourceViewResolver"><beans:property name="prefix" value="/WEB-INF/views/" /><beans:property name="suffix" value=".jsp" /></beans:bean><!-- Configuring interceptors based on URI --><interceptors><interceptor><mapping path="/home" /><beans:bean class="com.journaldev.spring.RequestProcessingTimeInterceptor"></beans:bean></interceptor></interceptors><context:component-scan base-package="com.journaldev.spring" /></beans:beans>


过滤器和拦截器的区别:

  ①拦截器是基于Java的反射机制的,而过滤器是基于函数回调。
  ②拦截器不依赖与servlet容器,过滤器依赖与servlet容器。
  ③拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用。
  ④拦截器可以访问action上下文、值栈里的对象,而过滤器不能访问。
  ⑤在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次。

  ⑥拦截器可以获取IOC容器中的各个bean,而过滤器就不行,这点很重要,在拦截器里注入一个service,可以调用业务逻辑。



2. 请求处理流程图



Spring工作流程描述
      1. 用户向服务器发送请求,请求被Spring 前端控制Servelt DispatcherServlet捕获;
      2. DispatcherServlet对请求URL进行解析,得到请求资源标识符(URI)。然后根据该URI,调用HandlerMapping获得该Handler配置的所有相关的对象(包括Handler对象以及Handler对象对应的拦截器),最后以HandlerExecutionChain对象的形式返回;
      3. DispatcherServlet 根据获得的Handler,选择一个合适的HandlerAdapter。(附注:如果成功获得HandlerAdapter后,此时将开始执行拦截器的preHandler(...)方法
       4.  提取Request中的模型数据,填充Handler入参,开始执行Handler(Controller)。 在填充Handler的入参过程中,根据你的配置,Spring将帮你做一些额外的工作:
      HttpMessageConveter: 将请求消息(如Json、xml等数据)转换成一个对象,将对象转换为指定的响应信息
      数据转换:对请求消息进行数据转换。如String转换成Integer、Double等
      数据根式化:对请求消息进行数据格式化。 如将字符串转换成格式化数字或格式化日期等
      数据验证: 验证数据的有效性(长度、格式等),验证结果存储到BindingResult或Error中
      5.  Handler执行完成后,向DispatcherServlet 返回一个ModelAndView对象;
      6.  根据返回的ModelAndView,选择一个适合的ViewResolver(必须是已经注册到Spring容器中的ViewResolver)返回给DispatcherServlet ;
      7. ViewResolver 结合Model和View,来渲染视图
      8. 将渲染结果返回给客户端。

Spring工作流程描述
    为什么Spring只使用一个Servlet(DispatcherServlet)来处理所有请求?
     详细见J2EE设计模式-前端控制模式
    Spring为什么要结合使用HandlerMapping以及HandlerAdapter来处理Handler?
    符合面向对象中的单一职责原则,代码架构清晰,便于维护,最重要的是代码可复用性高。如HandlerAdapter可能会被用于处理多种Handler


3. 事件传播



0 0