请求到达前端控制器,前端控制器先执行拦截器的preHandle方法,如果不想请求继续往下执行可以做处理。否则继续执行Controller的相关方法,等Controller的相关方法执行完后再执行拦截器的postHandle,最后会去执行afterCompletion。
后端控制器方法执行之前,先执行拦截器
preHandle()
,后端控制器方法执行结束之后,执行的是拦截器的postHandle()
,当前端控制器解析控制层返回的ModelandView并交给视图解析器渲染解析完成后,才会执行拦截器的afterCompletion()
方法。
自定义注解
/spring-mvc-v2/src/main/java/com/in/annotation/TimeMonitor.java
package com.in.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)//定义注解运行时有效
@Target(ElementType.METHOD)//target用于描述注解修饰方法
public @interface TimeMonitor {
}
配置拦截器的重点部分
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**" />
<mvc:exclude-mapping path="/doStudyInterceptor.do" />
<bean class="com.in.interceptor.TimeInterceptor" />
</mvc:interceptor>
</mvc:interceptors>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:util="http://www.springframework.org/schema/util" xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-4.3.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<!-- 配置spring中bean对象的扫描(包括后端控制器) component-scan元素用于包以及包中的子类并且将使用了@Controller,@Service类似注解等修饰的类
交给Spring容器管理。 -->
<context:component-scan base-package="com.in" />
<!--配置和启用spring MVC默认配置(例如底层支持json) -->
<mvc:annotation-driven />
<!--配置springMVC视图解析器(负责视图解析操作) -->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--前缀 -->
<property name="Prefix" value="/WEB-INF/pages/"></property>
</bean>
<!--配置拦截器对象 -->
<mvc:interceptors>
<mvc:interceptor>
<!--要拦截的路径url -->
<mvc:mapping path="/**" />
<!--要排除的拦截路径url -->
<mvc:exclude-mapping path="/doStudyInterceptor.do" />
<!--拦截器对象 -->
<bean class="com.in.interceptor.TimeInterceptor" />
</mvc:interceptor>
</mvc:interceptors>
</beans>
package com.in.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.in.annotation.TimeMonitor;
@Controller
@RequestMapping("/")
public class InterceptorController {
@RequestMapping("doSomeThing")
@ResponseBody
@TimeMonitor
public String doSomeThing() {
System.out.println("InterceptorController.doSomeThing()");
// 获取方法执行时长
String result = "do some thing";
try {
Thread.sleep(500);
} catch (Exception e) {
}
return result;
}
@RequestMapping("doStudyInterceptor")
@ResponseBody
public String doStudyInterceptor() {
System.out.println("InterceptorController.doStudyInterceptor()");
// 获取方法执行时长
String result = "do study Interceptor";
try {
Thread.sleep(600);
} catch (Exception e) {
}
return result;
}
@RequestMapping("doStudyMVC")
@ResponseBody
public String doStudyMVC(){
System.out.println("InterceptorController.doStudyMVC()");
String result = "do study MVC";
try {
Thread.sleep(700);
} catch (Exception e) {
}
return result;
}
}
package com.in.interceptor;
import java.lang.reflect.Method;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import com.in.annotation.TimeMonitor;
/**
* 拦截器的编写:是实现HandlerInterceptor接口或继承HandlerInterceptorAdapter 继承适配器只需要实现一部分功能
* 拦截器的配置 1)xml方式(spring-config.xml) 2)基于annotation方式
*/
public class TimeInterceptor implements HandlerInterceptor {
public TimeInterceptor() {
System.out.println("TimeInterceptor.TimeInterceptor()");
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
System.out.println("TimeInterceptor.preHandle()");
long startTime = System.currentTimeMillis();
HandlerMethod hMethod = (HandlerMethod) handler;
TimeMonitor timeMonitor = hMethod.getMethodAnnotation(TimeMonitor.class);
if (timeMonitor != null) {
// 没有共享就没有伤害
request.setAttribute("startTime", startTime);
}
return true;// false表示拦截。true表示放行
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
System.out.println("TimeInterceptor.postHandle()");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
System.out.println("TimeInterceptor.afterCompletion()");
System.out.println(handler.getClass().getName());
// 将handler向下转型(目的获取方法信息)
if (handler instanceof HandlerMethod) {
// 将handler向下转型-获取方法相关信息
HandlerMethod hMethod = (HandlerMethod) handler;
TimeMonitor timeMonitor = hMethod.getMethodAnnotation(TimeMonitor.class);
if (timeMonitor != null) {
// 没有共享就没有伤害
long endTime = System.currentTimeMillis();
long startTime = (Long) request.getAttribute("startTime");
long totalTime = endTime - startTime;
// 获取方法对象
Method method = hMethod.getMethod();
// 获取执行方法所在的类的信息
String beanCls = hMethod.getBeanType().getName();
System.out.println(beanCls + "." + method.getName() + "()" + "总时长" + totalTime);
}
}
}
}
http://localhost/spring-mvc-v2/doSomeThing.do
TimeInterceptor.preHandle()
InterceptorController.doSomeThing()
TimeInterceptor.postHandle()
TimeInterceptor.afterCompletion()
org.springframework.web.method.HandlerMethod
com.in.controller.InterceptorController.doSomeThing()总时长501
http://localhost/spring-mvc-v2/doStudyMVC.do
TimeInterceptor.preHandle()
InterceptorController.doStudyMVC()
TimeInterceptor.postHandle()
TimeInterceptor.afterCompletion()
org.springframework.web.method.HandlerMethod
http://localhost/spring-mvc-v2/doStudyInterceptor.do
InterceptorController.doStudyInterceptor()