【Spring面试】九、Spring MVC相关

文章目录

  • Q1、Spring事件监听的核心机制是什么?
  • Q2、Spring框架中都用到了哪些设计模式?
  • Q3、Spring是如何整合MyBatis来管理Mapper接口的?
  • Q4、说说SpringMVC如何解决GET和POST的乱码问题的?
  • Q5、Spring MVC的控制器是不是单例模式,如果是,有什么问题?如何解决?
  • Q7、描述SpringMVC的工作流程?
  • Q8、Spring MVC中处理AJAX请求的原理?
  • Q9、Spring搭配SpringMVC为什么需要父子容器?
  • Q10、是否可以把Spring MVC的所有Bean都交给Spring容器来管理?
  • Q11、是否可以把Spring的Bean都交给Spring MVC来管理?
  • Q12、如何实现零配置的Spring MVC?原理是什么?
  • Q13、SpringMVC的拦截器和过滤器有什么区别?

Q1、Spring事件监听的核心机制是什么?

前置知识补充:

关于事件监听,有三大部分:

  • 事件
  • 监听器
  • 发布器(Spring提供)

用法demo,发布事件:(默认同步,发布完事件后,等待监听器执行后,再往下继续执行。异步事件发布是多线程。)

【Spring面试】九、Spring MVC相关_第1张图片

监听器:

【Spring面试】九、Spring MVC相关_第2张图片

以上这种模式主要是为了实现业务的解耦,提高可扩展性和可维护性。当然这种需求在微服务中用MQ更多一些。

答案:

Spring事件监听的核心机制是观察者模式。Spring事件监听由三部分组成:

  • 事件(ApplicationEvent) :可以自己创建,Spring内部也创建了一些事件
    【Spring面试】九、Spring MVC相关_第3张图片

  • 监听器(ApplicationListener) :对应于观察者模式中的观察者。监听器监听特定事件,并在内部定义了事件发生后的响应逻辑

  • 事件发布器 (ApplicationEventMulticaster) :对应于观察者模式中的被观察者/主题,负责通知观察者 对外提供发布事件和增删事件监听器的接口,维护事件和事件监听器之间的映射关系,并在事件发生时负责通知相关监听器

Q2、Spring框架中都用到了哪些设计模式?

答案:

  • 1.简单工厂:BeanFactory
  • 2.工厂方法:FactoryBean
  • 3.单例模式:Bean实例
  • 4.适配器模式:SpringMVC中的HandlerAdatper
  • 5.装饰器模式:BeanWrapper
  • 6.代理模式:AOP底层
  • 7.观察者模式:spring的事件监听
  • 8.策略模式:exdludeFilters、indludeFilters
  • 9.横版方法模式:Spring几乎所有的外接扩展都采用这种模式
  • 10.责任链模式:Aop的方法调用

Q3、Spring是如何整合MyBatis来管理Mapper接口的?

答案:

  • 1.首先MyBatis的Mapper接口(没有实现类)核心是JDK动态代理
  • 2.Spring会排除接口(和抽象类),无法注册到IOC容器中
  • 3.MyBatis 实现了BeanDefinitionRegistryPostProcessor ,可以动态注册BeanDefinition
  • 4.需要自定义扫描器(继承Spring内部扫描器ClassPathBeanDefinitionScanner) 重写排除接口的方法 isCandidateComponent)
  • 5.但是接口虽然注册成了BeanDefinition,但是无法实例化Bean( 因为接口不能new对象)
  • 6.需要将BeanDefinition的BeanClass 替换成JDK动态代理的实例 (偷天换日)
  • 7.Mybatis 通过FactoryBean的工厂方法设计模式可以自由控制Bean的实例化过程,可以在getObject方法中创建JDK动态代理

Q4、说说SpringMVC如何解决GET和POST的乱码问题的?

答案:

在web.xml中配置一个CharacterEncodingFilter过滤器,设置成utf-8:
【Spring面试】九、Spring MVC相关_第4张图片
对于GET请求中文参数乱码,有两种思路:一是修改tomcat配置文件添加编码与工程编码一致:

<ConnectorURIEncoding="utf-8" connectionTimeout="20000" port="8880" protocol="HTTP/1.1" redirectPort="8443"/>

另一种是对参数进行重新编码:

String userName = new String(request.getParamter
	.getBytes("ISO8859-1"),"utf-8");

Q5、Spring MVC的控制器是不是单例模式,如果是,有什么问题?如何解决?

答案:

默认是单例模式,此时如果在类里声明成员变量,且两个线程对这个成员变量进行读写操作,就会有线程安全的问题。解决思路有:

  • 成员变量声明在方法中(局部变量)
  • 使用ThreadLocal绑定在本地线程中
  • 加同步锁(影响吞吐,并行变串行)

Q7、描述SpringMVC的工作流程?

等价问题:
描述下DispatchServlet的工作流程?

答案:

【Spring面试】九、Spring MVC相关_第5张图片

  • 用户发送请求至前端控制器DispatcherServlet
  • DispatcherServlet收到请求后,调用HandlerMapping处理器映射器,请求获取Handle
  • 处理器映射器根据请求ur找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成),一并返回给DispatcherServlet
  • DispatcherServlet 调用 HandlerAdapter处理器适配器
  • HandlerAdapter 经过适配调用具体处理器(Handler,也叫后端控制器)
  • Handler执行完成返回ModelAndView
  • HandlerAdapter将Handler执行结果ModelAndView返回给DispatcherServlet
  • DispatcherServlet将ModelAndView传给ViewResolver视图解析器进行解析
  • ViewResolver解析后返回具体View
  • DispatcherServlet对View进行渲染视图 (即将模型数据填充至视图中)
  • DispatcherServlet响应用户

Q8、Spring MVC中处理AJAX请求的原理?

答案:

  • 加入json和Java对象互转的依赖Jackson.jar(也可用其他的jar)
  • 在配置我呢见中配置json的消息转换器(Jackson不需要该配置HttpMessageConverter)

<mvc:annotation-driven conversion-service="conversionService">mvc:annotation-driven>
  • SpringMVC对数据Message的处理操作提供了个接门HttpMessageConverter,用来对参数值和返回值的转换处理,在请求和返回过程中可以进行转换json和Java对象
    【Spring面试】九、Spring MVC相关_第6张图片

接上个问题,加入消息转换器:

【Spring面试】九、Spring MVC相关_第7张图片

Q9、Spring搭配SpringMVC为什么需要父子容器?

答案:

就功能性来说不用子父容器也可以完成 (参考:springBoot就没用子父容器),使用父子容器,原因有:

  • 父子容器的主要作用应该是划分框架边界,有点单一职责的味道。service、dao层的Bean一般使用spring框架来管理,controller层的Bean则交给springmvc管理
  • 规范整体架构,(父子容器有个特性,子容器可以访问父容器中的Bean,父容器不能访问子容器中的Bean)使父容器service中无法访问子容器controller、子容器controller可以访问父容器service(Controller中注入Service的Bean,Service不能注入Controller中的Bean)
  • 方便子容器的切换,如果现在我们想把web层从spring mvc替换成struts,那么只需要将spring-mvc.xml替换成struts的配置文件struts.xm1即可,而spring-core.xml不需要改变

Q10、是否可以把Spring MVC的所有Bean都交给Spring容器来管理?

答案:

不可以,这样会导致我们请求接口的时候产生404。 如果所有的Bean都交给父容器,SpringMVC在初始化HandlerMethods的时候(initHandlerMethods) ,无法根据Controller的handler方法注册HandlerMethod,并没有去查找父容器的bean,也就无法根据请求URI 获取到 HandlerMethod来进行匹配。

在这里插入图片描述

Q11、是否可以把Spring的Bean都交给Spring MVC来管理?

答案:

可以,因为父容器的体现无非是为了获取子容器不包含的bean,如果全部包含在子容器完全用不到父容器了,所以是可以全部放在springmvc子容器来管理的。

虽然可以这么做不过一般应该是不推荐这么去做的,一般人也不会这么干的。如果你的项目里有用到事务、或者aop记得也需要把这部分配置需要放所以如到Spring-mvc子容器的配置文件来,不然一部分内容在子容器和一部分内容在父容器,可能就会导致你的事务或者AOP不生效。所以如果aop或事务不生效也有可能是通过父容器(spring)去增强子容器(Springmvc),也就无法增强。

Q12、如何实现零配置的Spring MVC?原理是什么?

答案:

第一种方式就是使用注解代替web.xml文件,相关注解:

  • @WebServlet
  • @WebListener
  • @WebFilter

第二种是基于SPI来实现:

省略web.xml
  • a. servlet3.0之后规范中提供了SPI扩展:META-INF/services/iavax.servlet.ServletContainerlnitializer
  • b.SpringMVC通过实现ServletContainerlnitializer接口
  • c.动态注册ContextLoaderListener 和DispatcherServlet并创建子父容器(Application)
省略spring.xml和spring-mvc.xml(只是springmvc方式,springboot在自动配置类完成) 配置类--xml
  • a.实现一个继承AbstractAnnotationConfigDispatcherServletlnitializer的类
  • b. 该类就实现了ServletContainerlnitializer,它会创建ContextLoaderListener 和DispatcherServlet
  • c.还会创建父子容器,创建容器时传入父子容器配置类则可以替代spring.xm和spring-mvc.xml

Q13、SpringMVC的拦截器和过滤器有什么区别?

答案:

  • 拦截器不依赖于servlet容器,过滤器依赖与servlet容器。
  • 拦截器只能对action请求(DispatcherServlet 映射的请求)起作用,而过滤器则可以对几乎所有的请求起作用
  • 拦截器可以访问容器中的Bean(DI),而过滤器不能访问(基于spring注册的过滤器也可以访问容器中的bean)。

【Spring面试】九、Spring MVC相关_第8张图片

========
听吐了这节,对Spring MVC了解太少,后面再复习吧。。。。。

你可能感兴趣的:(面试,spring,面试,mvc)