spring boot实现AOP,Filter,Interceptor以及3个之间的区别和使用场景

普通的项目
项目:demo 输入: 进行测试

/**
 * 测试用的
 */
@RestController
public class Hellotroller {

    @GetMapping("/hello/{name}")
    public String hello(@PathVariable String name){
        return "hello " + name;
    }
}
  • spring boot实现AOP
/**
 * 计时所用的aop
 */
@Aspect
@Component
public class TimeAspect {

    @Around("execution(* com.example.demo.controller.*.*(..))")
    public Object handleControllerMethod(ProceedingJoinPoint pjp) throws Throwable {

      System.out.println("time aspect start");
        long start = new Date().getTime();

        // 获取methodInvoke
        Field proxy = pjp.getClass().getDeclaredField("methodInvocation");
        proxy.setAccessible(true);
        ReflectiveMethodInvocation methodInvoke = (ReflectiveMethodInvocation) proxy.get(pjp);

        // 获取增强的类
        String controller = methodInvoke.getMethod().getDeclaringClass().getName();
        // 获取增强的方法名
        String method = methodInvoke.getMethod().getName();
        // 获取增强方法的参数
        Object[] args = methodInvoke.getArguments();
        // Object[] args = pjp.getArgs();

        System.out.println("增强   的    类:"+ controller);
        System.out.println("增强   的  方法:"+ method);
        for (Object arg : args) {
            System.out.println("增强的方法的参数:"+ arg);
        }


        Object object = pjp.proceed();

       System.out.println("time aspect 耗时:"+ (new Date().getTime() - start));

       System.out.println("time aspect end");

        return object;
    }
}

运行结果:

time aspect start
增强   的    类:com.example.demo.controller.Hellotroller
增强   的  方法:hello
增强的方法的参数:springboot
time aspect 耗时:2
time aspect end
  • Filter
/**
 * 计时过滤器
 */
@Component
public class TimeFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("TimeFilter init");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
            throws IOException, ServletException {
        System.out.println("TimeFilter start");
        // 开始时间
        long start = new Date().getTime();
        // 过滤的实际业务
        chain.doFilter(request,response);
        // 结束时间
        long end = new Date().getTime();
        System.out.println("过滤用时:" + (end - start));
        System.out.println("TimeFilter end");
    }

    @Override
    public void destroy() {
        System.out.println("TimeFilter destroy");
    }
}

运行结果(注掉AOP)

TimeFilter start
过滤用时:23
TimeFilter end
  • Interceptor
/**
 * 时间拦截器
 */
@Component
public class TimeInterceptor implements HandlerInterceptor{
    /**
     *进入被拦截的方法体之前执行
     * @return 返回结果为false:不执行postHandle和afterCompletion
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) 
            throws Exception {
        System.out.println("preHandle start");
        // 将开始时间添加到requestWebConfig
        request.setAttribute("start",new Date().getTime());

        HandlerMethod object = (HandlerMethod)handler;
        // 被过滤的方法
        Method method = object.getMethod();
        // 被过滤的对象
        Object bean = object.getBean();
        System.out.println(method.getName());
        System.out.println(bean.getClass());
        return true;
    }

    /**
     *进入被拦截的方法体之后执行(一旦方法体中有异常,不执行)
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, 
                           Object handler, ModelAndView modelAndView) throws Exception {
        // 获取开始时间
        long start = (long)request.getAttribute("start");
        System.out.println("postHandle start");
        // 将开始时间从request移去
        request.removeAttribute("start");
        System.out.println("TimeInterceptor耗时:" + (new Date().getTime() - start));

    }

    /**
     *进入被拦截的方法体之后执行(始终进入)
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, 
                                Object handler, Exception ex) throws Exception {
        System.out.println("postHandle afterCompletion");

    }
}
/**
 * 计时拦截器--第二步
 */
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter{

    @Resource
    private TimeInterceptor timeInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        super.addInterceptors(registry);
        registry.addInterceptor(timeInterceptor);
    }
}

运行结果(注掉AOP和Filter)

preHandle start
hello
class com.example.demo.controller.Hellotroller
postHandle start
TimeInterceptor耗时:4241
postHandle afterCompletion
  • 区别
5.1 运行的周期

三者全部放在一起运行

TimeFilter start
preHandle start
hello
class com.example.demo.controller.Hellotroller
EnhancerBySpringCGLIB
EnhancerBySpringCGLIB
9146121b
time aspect start
增强   的    类:com.example.demo.controller.Hellotroller
增强   的  方法:hello
增强的方法的参数:springboot
time aspect 耗时:3
time aspect end
postHandle start
TimeInterceptor耗时:22
postHandle afterCompletion
过滤用时:27
TimeFilter end
可以看出运行顺序为:filter -> Interceptor(preHandle) ->aspect  ->  Interceptor(postHandle ) -> filter 

5.2 获取信息的区别

能否获取 aspect filter Interceptor
被影响的类 Y Y
被影响的方法 Y Y
被影响的方法的参数 Y
被影响的controller的请求和响应 Y Y

————————————————
版权声明:本文为CSDN博主「何安忆_」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/sinat_18114869/article/details/80181648

posted @ 2022-03-24 00:36  青取之于蓝  阅读(130)  评论(0编辑  收藏  举报