• 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

  • 相关阅读:
    mybatis中的#和$的区别
    spring ioc三种注入方式
    JSP中动态INCLUDE与静态INCLUDE的区别
    j2ee部分
    面试 框架部分
    注册Jdbc驱动程序的三种方式
    union和union all有什么不同?
    面试 JavaWeb 部分
    Cordova插件开发(iOS/Android)--看这篇就够了
    程序员,请不要只看技术
  • 原文地址:https://www.cnblogs.com/lucas1024/p/16047870.html
Copyright © 2020-2023  润新知