当前位置: 首页 > 科技观察

关于SpringAOP原理,SpringMVC流程的面试题

时间:2023-03-13 11:36:06 科技观察

SpringAOP,SpringMVC,这两个应该是国内面试的必考题,网上有很多答案,其实背一下就可以了。不过今天笔者就带大家深入浅出地讲解一下源码,看看他的原理。为了让印象更加深刻,可以在面试的时候游刃有余。SpringAOP原理简单说一下AOP的设计:每个Bean都会被JDK或者Cglib代理。要看有没有接口。每个bean都会有多个“方法拦截器”。注意:拦截器分为两层,外层由Spring内核控制,内层拦截器由用户设置,即AOP。调用代理方法时,首先经过外层拦截器,外层拦截器根据方法的各种信息判断该方法应该执行哪些“内层拦截器”。内层拦截器的设计就是责任链的设计。是不是很简单。其实楼主之前写过一个简单的例子,地址:http://thinkinjava.cn/2018/10/使用-Cglib-实现多代理/看完之后更简单。AOP可以分为2部分来拉,哦不,来分析。..***:代理的创建;第二:代理的调用。注意:我们尽量少贴代码,尽量用文字描述,因为面试的时候也是文字描述,你不可能把代码翻出来。..因此,这里有必要保持一定的简单性。想知道详细的可以看21接口的源码,想知道更详细的可以看SpringFramework***的master分支代码。代码位置:com.interface21.aop包下。开始分析(pull):1.代理创建(一步一步):首先需要创建一个代理工厂,这需要3个重要的信息:拦截器数组、目标对象接口数组、目标对象。在创建代理工厂时,默认会在拦截器数组的末尾添加一个默认的拦截器——用于最终调用目标方法。调用getProxy方法时,会根据接口数大于0的情况,返回一个代理对象(JDK或Cglib)。注意:创建代理对象时,会同时创建一个外层拦截器,这是Spring内核拦截器。用来控制整个AOP的流程。2.代理调用当调用代理对象时,会触发外层拦截器。外部拦截器根据代理配置信息创建内部拦截器链。创建过程中会根据表达式判断当前拦截是否匹配这个拦截器。而这个拦截链设计模式就是责任链模式。当整个链条执行到***时,会触发创建代理时末尾的默认拦截器,从而调用目标方法。***返回。题外话:Spring的事务也是拦截器。这里有一个不是很标准的UML图:关于调用过程,这里有一个流程图:大概是这样的。有关更多详细信息,请参阅源代码。如果还有不明白的可以咨询我。不知道这张图是不是很通俗易懂——如果萌新能看懂,至少可以称得上通俗易懂。SpringMVC流程从一张图开始:代码位置:com.interface21.web.servlet.DispatcherServlet#doService(没错就是Spring1.0的代码,路子很简单,15年后的现在的Spring太臃肿了开发。从学习的角度来说,接口21是最好的代码,不接受任何反驳)代码如下:1.设置属性//1.设置属性//Makewebapplicationcontextavailablerequest.setAttribute(WEB_APPLICATION_CONTEXT_ATTRIBUTE,getWebApplicationContext());//Makelocaleresolveravailablerequest.setAttribute(LOCALE_RESOLVER_ATTRIBUTE,this.localeResolver);//Makethemeresolveravailablerequest.setAttribute(THEME_RESOLVER_ATTRIBUTE,this.themeResolver);2、根据Request请求的URL获取对应的handler执行链,其实就是拦截器和Controller代理对象。//2。找到handler并返回执行链HandlerExecutionChainmappedHandler=getHandler(request);3.获取处理程序的适配器//Thiswillthrowanexceptionifnoadapterisfound//3.返回处理程序的适配器HandlerAdapterha=getHandlerAdapter(mappedHandler.getHandler());它是什么?HandlerAdapter评论说:此接口不适用于应用程序开发人员。它适用于想要开发自己的Web工作流程的处理程序。翻译:此接口不适用于应用程序开发人员。它适用于想要开发自己的Web工作流的处理程序。也就是说,如果你想在处理handler之前做一些操作,你可能需要这个,也就是适配handler。比如Spring的测试程序是这样做的:publicModelAndViewhandle(HttpServletRequestrequest,HttpServletResponseresponse,Objectdelegate)throwsIOException,ServletException{//你可能需要doSomething.......((MyHandler)delegate).doSomething(request);returnnull;}4.循环执行处理程序的预拦截器//4。循环执行handler的前置拦截器for(inti=0;i=0;i--){HandlerInterceptorinterceptor=mappedHandler.getInterceptors()[i];//post拦截interceptor.postHandle(request,response,mappedHandler.getHandler());}7.根据ModelAndView信息到View实例Viewview=null;if(mv.isReference()){//我们需要解析thisviewname//7.根据ModelAndView信息,得到View实例view=this.viewResolver.resolveViewName(mv.getViewName(),locale);}8.渲染视图返回//8。渲染视图返回view.render(mv.getModel(),request,response);