幼儿饰品瑜伽美体用品微软
投稿投诉
微软创意
爱情通信
用品婚姻
爱好看病
美体软件
影音星座
瑜伽周边
星座办公
饰品塑形
搞笑减肥
幼儿两性
智家潮品

老生常谈你真的理解过滤器拦截器ControllerAdvic

  面试官:说说过滤器和拦截器的区别?这个问题面试题库算是比较经典的,这两个我相信很多同学在工作中都有接触过,但如果没有经过系统的整理,还真的不好说出个123来,那老湿机在此这面就把它俩和常用的AOP、ControllerAdvice放一起,带你做一个比较全面的认识。1。了解4种拦截方法的执行顺序
  先上一个栗子,看四种拦截方法并驾齐驱使用时,谁先谁后:Filter过滤器Slf4jWebFilter(urlPatterns)publicclassDemoFilterimplementsFilter{OverridepublicvoiddoFilter(ServletRequestrequest,ServletResponseresponse,FilterChainfilterChain)throwsIOException,ServletException{log。info(Filter进入);filterChain。doFilter(request,response);log。info(Filter退出);}}lInterceptor过滤器publicclassDemoInterceptorimplementsHandlerInterceptor{OverridepublicbooleanpreHandle(HttpServletRequestrequest,HttpServletResponseresponse,Objecthandler)throwsException{log。info(InterceptorpreHandle进入);returntrue;}OverridepublicvoidpostHandle(HttpServletRequestrequest,HttpServletResponseresponse,Objecthandler,ModelAndViewmodelAndView)throwsException{log。info(InterceptorpostHandle进入);}OverridepublicvoidafterCompletion(HttpServletRequestrequest,HttpServletResponseresponse,Objecthandler,Exceptionex)throwsException{log。info(InterceptorafterCompletion进入);}}ControllerAdviceControllerAdvicepublicclassDemoControllerAdvice{InitBinderpublicvoidinit(WebDataBinderbinder){log。info(ControllerAdviceinit进入);binder。setFieldDefaultPrefix(user。);}ExceptionHandler(Exception。class)publicStringhandleException(Exceptione){log。info(ControllerAdvicehandleException进入);returnerror;}}AOPAspectComponentpublicclassDemoAspect{Pointcut((target(org。springframework。web。bind。annotation。RestController))within(cn。demo。api。。)execution(public(。。)))publicvoidpointcut(){}Around(valuepointcut())publicObjectaround(ProceedingJoinPointpjp)throwsThrowable{log。info(Aop进入);Objectproceedpjp。proceed();log。info(Aop退出);returnproceed;}}控制器入口RestControllerRequestMapping(demo)publicclassDemoController{RequestMapping(test)publicMapString,Stringtest(ModelAttribute(user)Useruser){log。info(业务:user。name:{},user。getName());MapString,StringresultnewHashMap(2);result。put(code,200);inti1;ii0;returnresult;}}复制代码
  定义好Demo示例,接着来一发:http:localhost:8080demotest?user。name宫三公子:结果:Filter进入InterceptorpreHandle进入ControllerAdviceinit进入Aop进入业务:user。name:宫三公子ControllerAdvicehandleException进入InterceptorafterCompletion进入Filter退出复制代码
  好了,我们似乎已经看到,4种拦截方法的执行顺序是这样子:
  2。知晓4种拦截方法应用场景
  那么针对这4种拦截方法,它们涉及的应用场景、实现技术、作用力度都各不相同,为了有一个比较清晰的对比,老司机我简单粗暴,直接整理好啦,大伙干:
  3。掌握4种拦截方法的原理
  如果只晓得执行顺序和应用场景可能过不了面试大大狠辣的毒眼,知其然并知其所以然,我们就自废10根头发,来研究一下它们的原理吧。3。1过滤器
  虽然一个过滤器在一次请求中只能调用一次,但是根据具体业务需求,可以生成多个不同类型的Filter并依次执行,这就是过滤器的链式调用,可以通过指定Order排序,值越小越靠前(默认根据Filter的名称进行自然排序),新建了4个Filter,Order依次为03,演示一波,符合预期:
  接下来我们关注整个链式调用的核心:FilterChain接口,内部定义了doFilter接口方法,tomcat容器提供了ApplicationFilterChain作为FilterChain的具体实现:publicfinalclassApplicationFilterChainimplementsFilterChain{privateApplicationFilterConfig〔〕filtersnewApplicationFilterConfig〔0〕;privateServletservlet;publicvoiddoFilter(ServletRequestrequest,ServletResponseresponse){internalDoFilter(request,response);}privatevoidinternalDoFilter(ServletRequestrequest,ServletResponseresponse){if(this。posthis。n){ApplicationFilterConfigfilterConfigthis。filters〔this。pos〕;FilterfilterfilterConfig。getFilter();filter。doFilter(request,response,this);}else{this。servlet。service(request,response);}}}复制代码
  内部定义了ApplicationFilterConfig〔〕filters过滤器配置列表,每一个ApplicationFilterConfig内部持有一个Filter实例,另一个比较重要的是Servlet,实例化后对应原生HttpServlet或SpringMVC的DispatcherServlet,当拦截器链路执行完成后,会调用Servlet中service方法做后续的Url路由映射、业务处理以及视图响应等流程了(这个后面研究SpringMVC的请求流程来详细再分析),好了,我们通过Debug可以看到,filters中除了服务默认的一些请求filter,我们自己定义的4个filter也以定义好的顺序排入其中了:
  过滤器整体执行流程Likethis:
  3。2拦截器
  拦截器调用流程比较复杂,我这面根据源码梳理了核心请求流程和简要说明,感兴趣的同学可以继续一探究竟:源码位于:org。springframework。web。servlet。DispatcherServletdoDispatch方法
  Tip一下:网上有些朋友说拦截器是基于反射、动态代理来实现的,通过司机对源码分析,反射倒是有用到,主要从Spring的IOC容器中获取了拦截器对象,并放在AbstractHandlerMapping的adaptedInterceptors全局对象中,在上图的第二步就匹配满足的拦截器作为当前请求的拦截器列表,没有动态代理就没有影子!。3。3ControllerAdvice
  其实,ControllerAdvice和拦截器实现有异曲同工之处,要是说用什么技术手段,那应该也只能说是反射吧,在也主要在上一步的doDispatch方法中,它主要是在分布第4步t通过反射对InitBinder的参数的设置和第6步进行统一的异常捕获,重点看看第6步:在processDispatchResult处理结果方法内部,调用processHandlerException方法进行异常相关的处理逻辑,我们可以看到它的主要工作就是遍历handlerExceptionResolvers来进行异常对应的处理,我们自定义的全局异常ExceptionHandlerExceptionResolver实例控制着所有的Controller类,debug源码:
  那什么时候进行设置的以及如何设置的呢,值得我们思考一下,怀着好奇心,我们点开ExceptionHandlerExceptionResolver来看看,原来重点是实现了InitializingBean的afterPropertiesSet方法,在容器启动时候检测带ControllerAdvice注解的类和类中带ExceptionHandler注解的方法,并加入到我们刚才看到的exceptionHandlerCache中:publicclassExceptionHandlerExceptionResolverextendsAbstractHandlerMethodExceptionResolverimplementsApplicationContextAware,InitializingBean{privatefinalMapClasslt;?,ExceptionHandlerMethodResolverexceptionHandlerCachenewConcurrentHashMap(64);重点实现了afterPropertiesSetpublicvoidafterPropertiesSet(){this。initExceptionHandlerAdviceCache();}privatevoidinitExceptionHandlerAdviceCache(){if(this。getApplicationContext()!null){寻找所有带有ControllerAdvice注解的类ListControllerAdviceBeanadviceBeansControllerAdviceBean。findAnnotatedBeans(this。getApplicationContext());Iteratorvar2adviceBeans。iterator();while(var2。hasNext()){ControllerAdviceBeanadviceBean(ControllerAdviceBean)var2。next();Classlt;?beanTypeadviceBean。getBeanType();寻找该类下面的方法是否有ExceptionHandler注解,如果有,则收集到mappedMethods列表中ExceptionHandlerMethodResolverresolvernewExceptionHandlerMethodResolver(beanType);如果不为空,则加入到全局异常拦截缓存中if(resolver。hasExceptionMappings()){this。exceptionHandlerAdviceCache。put(adviceBean,resolver);}}}}}复制代码3。4AOP
  AOP这块想着网上其实很多同学梳理得很好了,到底要不要整理,但考虑到完整性,也避免同学们再额外找文章跳来跳去,就一并简化整理了,接着继续:前面说到,AOP是有两种实现方式,相信大家都耳熟能详:JDK动态代理和CGLib,带大家复习一下,先来一个JDK动态代理的栗子:1。动态代理是基于接口访问的,先定义用户服务接口publicinterfaceUserService{UsergetUser(Stringname);}2。具体用户服务实现类,也即被代理对象publicclassUserServiceImplimplementsUserService{OverridepublicUsergetUser(Stringname){UserusernewUser();user。setName(宫三公子);System。out。println(用户名:user。getName());returnuser;}}3。代理工具,用于服务增强publicclassJDKProxyrimplementsInvocationHandler{privateObjecttarget;publicJDKProxy(Objecttarget){this。targettarget;}OverridepublicObjectinvoke(Objectproxy,Methodmethod,Object〔〕args)throwsThrowable{System。out。println(beforeJDKProxy);Objectinvokemethod。invoke(target,args);通过反射执行,目标类的方法System。out。println(afterJDKProxy);returninvoke;}}4。测试方法publicclassJDKProxyTest{publicstaticvoidmain(String〔〕args){UserServiceImpluserServicenewUserServiceImpl();JDKProxyhandlernewJDKProxy(userService);UserServiceproxyInstance(UserService)Proxy。newProxyInstance(userService。getClass()。getClassLoader(),userService。getClass()。getInterfaces(),handler);UseruserproxyInstance。getUser(宫三公子);}}复制代码
  测试结果:beforeJDKProxy用户名:宫三公子afterJDKProxy复制代码
  CGLib的代理方式是为我们需要被代理的具体类生成一个子类,即将需被代理的方法进行Override重写:CGLib代理工具,用于生成业务增强publicclassCGLibProxyimplementsMethodInterceptor{publicObjectintercept(Objectarg0,Methodmethod,Object〔〕objects,MethodProxyproxy)throwsThrowable{System。out。println(beforeCGLibProxy);Objectresultproxy。invokeSuper(arg0,objects);System。out。println(afterCGLibProxy);returnresult;}}测试方法publicclassCGLibProxyTest{publicstaticvoidmain(String〔〕args){CGLibProxyproxynewCGLibProxy();EnhancerenhancernewEnhancer();enhancer。setSuperclass(UserServiceImpl。class);回调方法的参数为代理类对象CglibProxy,最后增强目标类调用的是代理类对象CglibProxy中的intercept方法enhancer。setCallback(proxy);UserServiceImpluserService(UserServiceImpl)enhancer。create();userService。getUser(宫三公子);打印增强效果System。out。println(打印userService的增强结果:);ReflectUtils。printMethods(userService。getClass());}}复制代码
  打印结果,我们可以看到被代理的方法已经执行了增强逻辑:beforeCGLibProxy用户名:宫三公子afterCGLibProxy打印userService的增强结果:publicfinalgetUser(java。lang。String);publicsetCallback(int,net。sf。cglib。proxy。Callback);publicstaticCGLIBfindMethodProxy(net。sf。cglib。core。Signature);publicstaticCGLIBSETTHREADCALLBACKS(〔Lnet。sf。cglib。proxy。Callback;);publicstaticCGLIBSETSTATICCALLBACKS(〔Lnet。sf。cglib。proxy。Callback;);publicgetCallback(int);publicgetCallbacks();publicsetCallbacks(〔Lnet。sf。cglib。proxy。Callback;);privatestaticfinalCGLIBBINDCALLBACKS(java。lang。Object);staticCGLIBSTATICHOOK1();finalCGLIBhashCode3();finalCGLIBclone4();finalCGLIBtoString2();finalCGLIBequals1(java。lang。Object);finalCGLIBgetUser0(java。lang。String);publicfinalequals(java。lang。Object);publicfinaltoString();publicfinalhashCode();protectedfinalclone();publicnewInstance(〔Lnet。sf。cglib。proxy。Callback;);publicnewInstance(〔Ljava。lang。Class;,〔Ljava。lang。Object;,〔Lnet。sf。cglib。proxy。Callback;);publicnewInstance(net。sf。cglib。proxy。Callback);复制代码
  好了,我们看完了基于Jdk动态代理和CGLib代理的两种Demo,那我们继续看看Spring是怎么玩的吧。在Spring的启动过程中,有很多的扩展点,比较让我们熟知的BeanPostPorcessor,主要在Bean进行initializeBean初始化后,调用org。springframework。beans。factory。support。AbstractAutowireCapableBeanFactoryapplyBeanPostProcessorsAfterInitialization,内部对所有的BeanPostPorcessor对象进行遍历,调用postProcessAfterInitialization进行处理,而Aop就是基于该扩展点实现的:
  沿着这条链路Debug调试,最终可以定位到具体决定调用JDK动态代理还是使用CGLib,我这代理的是DemoController,那生成的就是CGLig代理啦:
  OK,关于过滤器、拦截器、ControllerAdvice以及AOP,本文从执行顺序、应用场景、实现技术以及原理等进行了总结,看完了,朋友们如果有收获就是对我最大得肯定。
  来源:https:juejin。cnpost7212175872091029559

官方旗舰店外,南极人为何还有各种电商专卖店?卖吊牌是一门好生时值冬日,消费者王小姐在某电商平台买了一件南极人牌的羽绒服,收到货品后却发现货不对板,与店家沟通无果只能选择去黑猫平台上投诉。在黑猫投诉平台上,关于南极人的各类投诉事件近……讽刺日本捕鲸业,与环保反战主题,别觉得阿凡达2只是科幻片有人说,这时候去看《阿凡达:水之道》的只有2种人:一种是影迷,一种是发烧友。他们梦寐以求的文明,正发生在眼前更大的潘多拉世界。我仍记得,2010年电影院,人们……3万元左右,能买到哪些平价防磁腕表?〔腕表之家腕表推荐〕防磁表有着很高的实用价值,并且受到很多表友的青睐,今天腕表之家为朋友们推荐三只防磁的腕表,价格都在3万元左右,有这类需求的表友,可以参考一下!帝舵碧湾……娱乐圈假戏真做的揩油咸猪手,娱乐圈畸形现象何时是头?影视圈娱乐圈作为一个公众的圈层,应该倡导文明,传输正确的三观给大众,但是一些低素质艺人以戏之名,行之不轨,品德败坏。某档综艺节目为了舞台还原(闯关东)的情节,于是请韩兆和……难阻失利!特雷杨白砍23分10助攻,老鹰7分不敌雷霆北京时间2022年12月6日讯,老鹰以114:121,7分分差不敌对手雷霆。首节比赛开始,卡佩拉与RobinsonEarl跳球,约翰逊得到球。基迪杰伦威廉姆斯外线接一下。……特斯拉百万级重卡的技术,能用在20多万的Model3上?已经有这么多纯电车型上路了,为什么雾霾天气还会时不时地卷土重来?机动车排放确实是影响空气质量的一个重要因素,虽然小汽车排放标准不断提升,新能源车型越来越多,但是那些一台就有着相……数字人民币来佛山啦容桂市民尝鲜数字人民币支付。广州日报讯(全媒体记者王名润)数字人民币来佛山啦!昨日,数字人民币体验活动暨容光焕发大展宏兔2023容桂年货节活动启动仪式在顺德海骏达城举行。……东北有座长白山千年积雪万年松,直上人间第一峰说起东北的名山,第一想到的就是长白山。在人们心中,长白山是一座神山,从古至今从未停止对她的神往与想象。她是关东各族人繁衍生息的摇篮,从天女不孕而育的发祥传说,长相守到白头……全国第八!合肥这么热这个中秋在严格落实疫情防控措施的前提下市民游客在合肥度过了仪式感十足的我们的节日中秋合肥周边游人数冲到全国前十9月12日,携程发布《2022……IPO雷达背靠镍王,动力电池生产商瑞浦兰钧拟赴港上市,三年半记者张乔遇镍王青山集团欲将旗下首个动力电池制造厂送上资本市场。近日,瑞浦兰钧能源股份有限公司(简称:瑞浦兰钧)向港交所递交首次公开发行上市招股书。瑞浦兰钧的背后是世……把嘴炮打骨折的普瓦里尔刚出院后又住进医院,并接受了手术达斯汀普瓦里尔在脚部感染导致再次入院后成功接受了手术UFC轻量级拳手钻石达斯汀普瓦里尔(DustinPoirier)在接受脚部手术后正在康复。据普瓦里尔的妻子朱莉(……恩爱夫妻,终于装不下去了?没有人能拒绝高情商的女生,尤其是鲍蕾!当看到老公陆毅给自己递包,她奶声奶气地回道:我就知道你会给我拿包的,谢谢老公。陆毅的画被隔壁郑恺公然嘲讽。虽然画的确实不……
转型中的小米图片来源视觉中国文光子星球,作者吴先之,编辑王潘8月19日,小米披露2022年第二季度与半年报,数据显示,Q2小米实现营收702亿元,同比下滑20,经调净利润21亿……人生赢家伊戈达拉很多球迷朋友,在提到伊戈达拉,第一时间想到的是抱勇士大腿,14赛季抢走库里总决赛MVP,混了4枚总冠军戒指,可在我看来,伊戈达拉就他NBA球员生涯来看,他是妥妥的人生赢家。……他,30岁获杰青资助,40岁评上院士,刚刚团队成果登上Nat考研经验大家谈反芳香丁富烯的通用构筑方法自从1865年凯库勒首次提出苯环的结构以来,人们开发了大量关于苯及其衍生物的合成方法。在苯环的结构中,由于存在六元环的电子结……Web3。0,泡沫还是机遇?来源Tech数字星球山雨欲来风满楼。关于Web3,从业者的呐喊声、旁观者的议论声犹如洪水一般袭来,有期待、有追捧、有质疑,到底哪一个描述才是真实的Web3?有人说所……华硕也出手了,DIY电竞电脑未来者降价,配RTX3060售5前几天,我们介绍了联想的DIY品牌异能者,这几天,华硕的DIY品牌未来者就来了,其也是明显标注各种配件的厂家,型号,并提供3年质保,预装系统,让我们来看看。可以看到,未来……罚罪最出人意料的卧底,特种强兵邱涛,最后命运让人担忧《罚罪》作为一部刑侦剧有两个类似无间道的看点:赵啸声手里的大王是谁?严国华手里的王牌卧底是谁?很多观众都会认为,这两个最隐秘的人物估计会一直潜伏到《罚罪》结尾,没想到的是……华为mate50懂的人都觉的值华为发布会结束了,欢喜忧愁各有见解,不友好的每年重复的酸和幽怨,不明真相的人一看价格也跟风点火,不过没有关系,喜欢还有理性的人一直会继续喜欢。为什么说华为的Mate经典款……热火与凯尔特人的完美交易,热火赢在未来,绿军现在就要夺冠凯尔特人夏天为了得到杜兰特,多次将杰伦布朗摆放在了谈判筹码中,这个行为无疑会伤害到布朗。尽管凯尔特人已经展开了安抚工作,但是破镜难重圆,裂痕已产生。凯尔特人对布朗的不尊重必然为……北极变暖速度全球第一,1。4万亿吨甲烷或被释放!会有什么后果在我们的印象中,地球的南极和北极应该是地球上最冷的区域,放眼望去一望无际的肯定是茫茫冰雪,在极夜期间天空中挂满的将是绚烂多彩的极光,冷寂用来形容地球的两极应该是再恰当不过了。但……你不了解的月嫂行业的前景,就会错失财富的光顾月嫂是专门照顾月子期间产妇和新生儿的一个职业,是集育婴师、催乳师、产康师、厨师、护士的工作性质于一身的高级家政服务人员。01hr育儿观念的转变中国目前的社会大环境、……5年击败阿里,耻与马云并肩,郭凡生为啥这么狂?1hr大家注意看这段视频。视频是2005年的一段央视财经节目《赢在中国》,视频中这位戴眼镜的中年人叫郭凡生,他正与台下的一名观众辩论:他创立的慧聪网和阿里巴巴,哪一个更有前途?……翟山鹰爆联想大料联想有关话题长期是民众和广大网民热议的话题,联想被热议的原因有很多,一是联想是知名科技公司,二是有关联想话题都是以前民众不知道的,三是联想有关话题和争议没有得到权威定论。……
友情链接:易事利快生活快传网聚热点七猫云快好知快百科中准网快好找文好找中准网快软网