5、spring boot + Maven + Restful filter+interceptor+Aspect

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_29451823/article/details/82775899
  1. 过滤器有两种创建方式,第一种需要直接实现Filter
package com.imooc.filter;

import java.io.IOException;
import java.util.Date;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

import org.springframework.stereotype.Component;

/**
 * 只需要声明Component注解就能起作用
 * @author caijiajun
 * @date   2018年9月11日
 */
@Component 
public class TimeFilter implements Filter {
	
	/**
	 *容器紧跟在垃圾收集之前调用 destroy()方法,以便能够执行任何必需的清理代码。
	 */
	@Override
	public void destroy() {
		System.out.println("time filter destroy");
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		System.out.println("time filter start");
		long start  = new Date().getTime();
		chain.doFilter(request, response);
		System.out.println("time filter:" +(new Date().getTime() - start));
		System.out.println("time filter finish");
	}

	@Override
	public void init(FilterConfig arg0) throws ServletException {
		System.out.println("time filter init");
	}

}

  1. 第二种实现过滤器实现一个WebMvcConfigurationAdapter加载适配器
package com.imooc.web.config;

import java.util.ArrayList;
import java.util.List;

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.AsyncSupportConfigurer;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

import com.imooc.filter.TimeFilter;
import com.imooc.web.interceptor.TimeInterceptor;

@Configuration
public class WebConfig extends WebMvcConfigurerAdapter{
	
	@Autowired
	private TimeInterceptor timeInterceptor;
	/**
	 * 自定义加载过滤器 
	 *spring中 filter是以 
	 *FilterRegistrationBean形式存在的,然后我们 
	 *setFilter为这个filter放入spring 容器管理。
	 *可以用setOrder方法为filter设置排序值
	 * @return
	 */
	@Bean
	public FilterRegistrationBean timeFilter() {
		FilterRegistrationBean  registrationBean = new FilterRegistrationBean();
		//加载过滤器
		TimeFilter timeFilter = new TimeFilter();
		registrationBean.setFilter(timeFilter);
		
		List<String> urls = new ArrayList<>(); 
		urls.add("/*");
		registrationBean.setUrlPatterns(urls);
		
		return registrationBean;
	}
	}

3.拦截器,拦截器的配置必须在重写注册,自定义拦截器TimeInterceptor类

package com.imooc.web.interceptor;

import java.util.Date;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

@Component
public class TimeInterceptor implements HandlerInterceptor {
	/**
	 * 无论如何都会被调用在postHandle后面,只有在preHandle返回true才会执行
	 * 在DispatcherServlet 渲染了对应的视图之后执行。用于进行资源清理。
	 */
	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object arg2, Exception ex)
			throws Exception {
		System.out.println("afterCompletion");
		long start = (long)request.getAttribute("startTime");
		System.out.println("time interceptor 耗时: " + (new Date().getTime() - start));
		System.out.println("ex :" + ex);
	}
	/**
	 * 控制器处理后被调用,如果controller方法抛出异常,就不会被调用
	 * 该方法将在请求处理之后,DispatcherServlet进行视图返回渲染之前进行调用
	 */
	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndeVidw)
			throws Exception {
		System.out.println("postHandle");
		long start = (long)request.getAttribute("startTime");
		System.out.println("time interceptor 耗时: " + (new Date().getTime() - start));
	}
	/**
	 * controller方法调用前被调用
	 * 只有该方法返回true,后面的Interceptor和cotroller才会被执行
	 */
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
		System.out.println("preHandle");
		//对应的类名
		System.out.println(((HandlerMethod)handler).getBean().getClass().getName());
		//对应的方法名
		System.out.println(((HandlerMethod)handler).getMethod().getName());
		request.setAttribute("startTime", new Date().getTime());
		return true;
	}

}

  1. 重写注册器,加载拦截器
package com.imooc.web.config;

import java.util.ArrayList;
import java.util.List;

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.AsyncSupportConfigurer;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

import com.imooc.filter.TimeFilter;
import com.imooc.web.interceptor.TimeInterceptor;

@Configuration
public class WebConfig extends WebMvcConfigurerAdapter{
		
	@Autowired
	private TimeInterceptor timeInterceptor;
	
	/**
	 * 自定义加载过滤器 
	 *spring中 filter是以 
	 *FilterRegistrationBean形式存在的,然后我们 
	 *setFilter为这个filter放入spring 容器管理。 
	 *可以用setOrder方法为filter设置排序值
	 * @return
	 */
	@Bean
	public FilterRegistrationBean timeFilter() {
		FilterRegistrationBean  registrationBean = new FilterRegistrationBean();
		//加载拦截器
		TimeFilter timeFilter = new TimeFilter();
		registrationBean.setFilter(timeFilter);
		
		List<String> urls = new ArrayList<>(); 
		urls.add("/*");
		registrationBean.setUrlPatterns(urls);
		
		return registrationBean;
	}
	/**
	 * 重写注册器  加载拦截器
	 */
	@Override
	public void addInterceptors(InterceptorRegistry registry) {
		registry.addInterceptor(timeInterceptor);
	}
	}

5 . Aspect增强

package com.imooc.web.aspect;

import java.util.Date;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class TimeAspect {
	

	/**
	 * 设置切入点
	 * proceedingJoinPoint 里面包含拦截的方法的信息
	 * @param proceedingJoinPoint
	 * @return
	 */
	@Around("execution(* com.imooc.web.controller.UserController.*(..))")
	public Object handleControllerMethod(ProceedingJoinPoint pjp) throws Throwable {
		System.out.println("time aspect start");
		//传入参数
		Object[] args = pjp.getArgs();
		for(Object arg : args) {
			System.out.println("args is "+arg);
		}
		long start = new Date().getTime();
		//调用被加强的方法、
		Object object = pjp.proceed();
		
		System.out.println("time aspect 耗时:" + (new Date().getTime() -start));
		System.out.println("time aspect end");
		return object;
	}
}

  1. 正常Controller运行Filter,interceptor,Aspect的顺序
    在这里插入图片描述
    总结:Filter(init) -> Filter(doFilter) -> interceptor(preHandle) -> Aspect(around) -> Controller
    -> Aspect(Around) ->interceptor(postHandle) -> interceptor(AfterCompletion) ->Filter(doFilter) -> Filter(destroy)
    注释:如果interceptor中prehandle()方法返回false 则不会进入后面两个方法,如果interceptor中prehandle()方法返回true,但是controller报异常,则不会进入postHandle()方法

猜你喜欢

转载自blog.csdn.net/qq_29451823/article/details/82775899
今日推荐