方式:java
一、FIlter過濾器web
二、interceptor攔截器spring
三、Aspect切片mvc
1、Filter過濾器形式app
只能處理request中的數據 不能肯定請求要走的是哪一個controller信息ide
一、過濾器實現第一種方式post
package com.nxz.filter; import org.springframework.stereotype.Component; import javax.servlet.*; import java.io.IOException; import java.util.Date; // Filter 是javax.servlet下的 @Component //讓自定義filter起做用,只須要讓springcontext管理起來便可 public class TimeFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { System.out.println("time filter init"); } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { System.out.println("time filter start"); long time = new Date().getTime(); filterChain.doFilter(servletRequest, servletResponse); System.out.println("消耗時間:" + (new Date().getTime() - time)); System.out.println("time filter start"); } @Override public void destroy() { System.out.println("time filter destroy"); } }
當項目啓動的時候會在控制檯輸出:time filter initspa
當訪問localhost:8080/user/1時:進入攔截器日誌
結束結束後:code
time filter start 進入getinfo服務 消耗時間:367 time filter end
二、filter過濾器第二種方式
package com.nxz.filter; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class WebConfig { @Bean public FilterRegistrationBean timeFilter(){ FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(); TimeFilter timeFilter = new TimeFilter(); filterRegistrationBean.setFilter(timeFilter); //指定什麼樣的請求回走timefilter過濾器 filterRegistrationBean.addUrlPatterns("/*"); return filterRegistrationBean; } }
2、inteceptor攔截器
只能處理到類中的方法,可是不能記錄方法的參數是什麼
package com.nxz.inteceptor; import org.springframework.stereotype.Component; import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.Date; @Component public class TimeInteceptor implements HandlerInterceptor { //在controller調用以前調用 @Override public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception { System.out.println("preHandler"); System.out.println(((HandlerMethod) o).getBean().getClass().getName());//輸出類名 System.out.println(((HandlerMethod) o).getMethod().getName());//輸出方法名 //爲了在prehandler方法和posthandler方法之間傳遞信息,能夠將數據放到request中 httpServletRequest.setAttribute("startTime", new Date().getTime()); return false; } //在controller調用以後調用,若是controller中拋出異常,這個方法不會調用 @Override public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception { System.out.println("postHandle"); Long start = (Long) httpServletRequest.getAttribute("startTime"); System.out.println("time interceptor 耗時:" + (new Date().getTime() - start)); } //不管controller是否拋出異常,都會調用 @Override public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception { System.out.println("afterCompletion"); Long start = (Long) httpServletRequest.getAttribute("startTime"); System.out.println("time interceptor 耗時:" + (new Date().getTime() - start)); System.out.println("ex is :" + e); } }
interceptor實現攔截功能還須要配置webconfig
package com.nxz.config; import com.nxz.filter.TimeFilter; import com.nxz.inteceptor.TimeInteceptor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; @Configuration public class WebConfig extends WebMvcConfigurerAdapter { @Autowired private TimeInteceptor timeInteceptor; //自定義的interceptor 要起做用的話 須要繼承webmvcConfigurerAdater ,重寫addInterceptors @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(timeInteceptor); } }
訪問localhost:8080/user/1後,輸入日誌:
preHandler com.nxz.controller.UserController getInfo 進入getinfo服務 postHandle time interceptor 耗時:48 afterCompletion time interceptor 耗時:48 ex is :null
3、切片Aspect(AOP) -- 切入點(註解)、加強(方法)
須要導入aop依賴
package com.nxz.aspect; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.springframework.stereotype.Component; import java.util.Date; @Aspect @Component public class TimeAspect { //@Before @After @AfterThrowing @Around 基本的aop註解 @Around("execution(* com.nxz.controller.UserController.*(..))") public Object handlerControllerMehtod(ProceedingJoinPoint joinPoint) throws Throwable { System.out.println("time aspect start"); Object[] args = joinPoint.getArgs(); for (Object arg : args) { System.out.println(arg); } Long time = new Date().getTime(); Object obj = joinPoint.proceed(); System.out.println("time aspect end,耗時:" + (new Date().getTime() - time)); return obj; } }
訪問地址後:
time aspect start 1 --》請求參數 進入getinfo服務 time aspect end,耗時:4
幾種方式起做用的順序:
====
Usercontroller:
@GetMapping("/{id:\\d+}") @JsonView(User.UserDetailView.class) public User getInfo(@PathVariable String id) { System.out.println("進入getinfo服務"); User user = new User(); user.setUsername("tom"); return user; }