2021年JAVA 精心整理的常见面试题-附详细答案 | https://mikejun.blog.csdn.net/article/details/114488339 |
2021年- 精心整理的 SpringMVC 常见面试题-【附详细答案】 | https://mikejun.blog.csdn.net/article/details/114992529 |
2021年JAVA 面试题之--数据结构篇【附详细答案】 | https://mikejun.blog.csdn.net/article/details/114647742 |
三天刷完《剑指OFFER编程题》--Java版本实现(第一天) | https://mikejun.blog.csdn.net/article/details/106996017 |
三天刷完《剑指OFFER编程题》--Java版本实现(第二天) | https://mikejun.blog.csdn.net/article/details/108098502 |
三天刷完《剑指OFFER编程题》--Java版本实现(第三天) | https://mikejun.blog.csdn.net/article/details/108253489 |
项目推荐:
Java微服务实战296集大型视频-谷粒商城【附代码和课件】
Java开发微服务畅购商城实战【全357集大项目】-附代码和课件
1. 请说一下SpringMVC 的执行流程
步骤:
1.用户向服务器发送请求,请求被 springMVC 前端控制器 DispatchServlet 捕获;
2.前端控制器请求处理器映射器:查询能够处理该请求的Controller
3.将找到的Controller路径返回给前端控制器.4.前端控制器请求处理器适配器: 找到能够处理该请求的处理器。
5.处理器执行请求代码。(controller-service-dao)
6.将处理后的结果和响应页面封装到ModelAndView对象中,返回给处理器适配器.
7.将ModelAndView对象返回给前端控制器.8.前端控制器请求视图解析器: 解析View对象,确定是哪个页面。
9.视图解析器内部拼接,将页面名称拼接成真实的页面路径,返回给前端控制器。(拼接前缀和后缀:View=hello -->(/WEB-INF/hello.jsp))
10.视图渲染(将数据填充到页面中(request域中)),最后将完整的view展示给用户。
2. Spring MVC的主要组件?
-
前端控制器 DispatcherServlet(不需要程序员开发)
作用:接收请求、响应结果,相当于转发器,有了DispatcherServlet 就减少了其它组件之间的耦合度。 -
处理器映射器HandlerMapping(不需要程序员开发)
作用:根据请求的URL来查找Handler -
处理器适配器HandlerAdapter
注意:在编写Handler的时候要按照HandlerAdapter要求的规则去编写,这样适配器HandlerAdapter才可以正确的去执行Handler。 -
处理器Handler(需要程序员开发)
-
视图解析器 ViewResolver(不需要程序员开发)
作用:进行视图的解析,根据视图逻辑名解析成真正的视图(view) -
视图View(需要程序员开发jsp)
View是一个接口, 它的实现类支持不同的视图类型(jsp,freemarker,pdf等等)
3. springMVC和struts2的区别有哪些?
-
springmvc的入口是一个servlet即前端控制器(DispatchServlet),而struts2入口是一个filter过虑器(StrutsPrepareAndExecuteFilter)。
-
springmvc是基于方法开发(一个url对应一个方法),请求参数传递到方法的形参,可以设计为单例或多例(建议单例),struts2是基于类开发,传递参数是通过类的属性,只能设计为多例。
-
Struts采用值栈存储请求和响应的数据,通过OGNL存取数据,springmvc通过参数解析器是将request请求内容解析,并给方法形参赋值,将数据和视图封装成ModelAndView对象,最后又将ModelAndView中的模型数据通过reques域传输到页面。Jsp视图解析器默认使用jstl。
4. 如何解决POST请求中文乱码问题,GET的又如何处理呢?
- 解决post请求乱码问题:
在web.xml中配置一个CharacterEncodingFilter过滤器,设置成utf-8;
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>
/*</url-pattern>
</filter-mapping>
- get请求中文参数出现乱码解决方法有两个:
- ①修改tomcat配置文件添加编码与工程编码一致,如下:
<ConnectorURIEncoding="utf-8" connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>
- ②另外一种方法对参数进行重新编码:
String userName = new String(request.getParamter("userName").getBytes("ISO8859-1"),"utf-8")
ISO8859-1是tomcat默认编码,需要将tomcat编码后的内容按utf-8编码。
5. SpringMVC常用的注解有哪些?
- @RequestMapping:用于处理请求 url 映射的注解,可用于类或方法上。用于类上,则表示类中的所有响应请求的方法都是以该地址作为父路径。
- @RequestBody:注解实现接收http请求的json数据,将json转换为java对象。
- @ResponseBody:注解实现将conreoller方法返回对象转化为json对象响应给客户。
6.SpringMvc的Controller是不是单例模式,如果是,有什么问题,怎么解决?
答:是单例模式,所以在多线程访问的时候有线程安全问题,会影响性能的。解决方案是尽量不要在Controller中使用类变量。
对于多例情况普通属性是不会共用的,对于静态属性会去共用这个属性。
对于单例情况普通属性和静态属性都会被共用。(controller默认为单例)
springmvc是基于方法开发的,方法里边的形参不会被共享,因此默认是多例。springmvc如果要使用类变量,需要定义为多例的。Struts是基于类的属性开发的,单例会共享属性,因此单例不安全,所以默认为多例。
7. 什么是MVC模式?
- MVC的全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,是一种软件设计典范。它是用一种业务逻辑、数据与界面显示分离的方法来组织代码,将众多的业务逻辑聚集到一个部件里面,在需要改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑,达到减少编码的时间。
- V即View视图是指用户看到并与之交互的界面。比如由html元素组成的网页界面,或者软件的客户端界面。MVC的好处之一在于它能为应用程序处理很多不同的视图。在视图中其实没有真正的处理发生,它只是作为一种输出数据并允许用户操纵的方式。
- M即model模型是指模型表示业务规则。在MVC的三个部件中,模型拥有最多的处理任务。被模型返回的数据是中立的,模型与数据格式无关,这样一个模型能为多个视图提供数据,由于应用于模型的代码只需写一次就可以被多个视图重用,所以减少了代码的重复性。
- C即controller控制器是指控制器接受用户的输入并调用模型和视图去完成用户的需求,控制器本身不输出任何东西和做任何处理。它只是接收请求并决定调用哪个模型构件去处理请求,然后再确定用哪个视图来显示返回的数据。
8. SpringMVC有哪些优点?
- SpringMVC本身是与Spring框架结合而成的,它同时拥有Spring的优点(例如依赖注入DI和切面编程AOP等)。
- SpringMVc提供强大的约定大于配置的契约式编程支持,即提供一种软件设计范式,减少软件开发人员做决定的次数,开发人员仅需规定应用中不符合约定的部分。
- 支持灵活的URL到页面控制器的映射。
- 可以方便地与其他视图技术(JSP、FreeMarker等)进行整合。由于SpringMVC的模型数据往往是放置在Map数据结构中的,因此其可以很方便地被其他框架引用。
- 拥有十分简洁的异常处理机制。
- 可以十分灵活地实现数据验证、格式化和数据绑定机制,可以使用任意对象进行数据绑定操作。
- 支持RestFul风格。
9. 当一个方法向AJAX返回特殊对象,譬如Object,List等,需要做什么处理?
- 在方法上加@ResponseBody注解,表示该方法的返回值不管是什么类型,都会返回JSON格式的数据。
- 把原来Controller类上的@Controller注解替换为@RestController注解。@RestController = @Controller + @ResponseBody,表明该Controller类所有的方法都返回JSON格式的数据(没有加@RequestMapping注解的方法除外)。
加入@ResponseBody注解就能返回JSON格式数据的原因是
:SpringMVC提供的HttpMessageConverter自动转为JSON ,如果使用了Jackson或者Gson,不需要额外配置就可以自动返回JSON了,因为框架帮我们提供了对应的HttpMessageConverter ,如果使用了Alibaba的Fastjson的话,则需要自己手动提供一个相应的 HttpMessageConverter的实例。
10.SpringMVC用什么对象从后台向前台传递数据的?
- 使用Map、Model和ModelMap的方式,这种方式存储的数据是在request域中
@RequestMapping("/getUser")
public String getUser(Map<String,Object> map,Model model,ModelMap modelMap){
//1.放在map里
map.put("name", "xq");
//2.放在model里,一般是使用这个
model.addAttribute("habbit", "Play");
//3.放在modelMap中
modelMap.addAttribute("city", "gd");
modelMap.put("gender", "male");
return "userDetail";
}
- 使用request的方式
@RequestMapping("/getUser")
public String getUser(Map<String,Object> map,Model model,ModelMap modelMap,HttpServletRequest request){
//放在request里
request.setAttribute("user", userService.getUser());
return "userDetail";
}
- 使用ModelAndView
@RequestMapping("/getUser")
public ModelAndView getUser(ModelAndView modelAndView) {
mav.addObject("user", userService.getUser());
mav.setViewName("userDetail");
return modelAndView;
}
11.怎么样把ModelMap里面的数据放入session里面?
在类上添加@SessionAttributes
注解将指定的Model数据存储到session中。
@SessionAttributes
- 默认情况下Spring MVC将模型中的数据存储到request域中。当一个请求结束后,数据就失效了。如果要跨页面使用。那么需要使用到session。而@SessionAttributes注解就可以使得模型中的数据存储一份到session域中。
- @SessionAttributes只能定义在Class,interface enum上,作用是将指定的Model中的键值对添加至session中,方便在一个会话中使用。
@SessionAttributes参数
- names:这是一个字符串数组。里面应写需要存储到session中数据的名称。
- types:根据指定参数的类型,将模型中对应类型的参数存储到session中。
- value:其实和上面的names是一样的。
@SessionAttributes(value={"names"},types={Integer.class})
@Controller
public class session{
@RequestMapping("/session")
public String session(Model model){
model.addAttributes("names", Arrays.asList("caoyc","zhh","cjx"));
model.addAttributes("age", 22);
return "/session";
}
}
在上面代码中,在类上添加@SessionAttributes注解,并指定将names名称的Model数据存储到session域中,以及将Integer类型的Model数据存储到session域中。
12.SpringMMV中有个类把视图和数据都合并的一起的,叫什么?
它就是ModelAndView。
- 使用ModelAndView类存储处理完后的结果数据,以及显示该数据的视图。从名字上看ModelAndView中的Model代表模型,View代表视图,从名字看就很好地解释了该类的作用。Controller处理器调用模型层处理完用户请求后,把结果数据存储在该类的model属性中,把要返回的视图信息存储在该类的view属性中,然后把ModelAndView返回给前端控制器。前端控制器通过调用配置文件中定义的视图解析器,对该对象进行解析,最后把结果数据显示在指定的页面上。
- 返回指定页面
ModelAndView构造方法可以指定返回的页面名称。
也可以通过setViewName()方法跳转到指定的页面 。- 返回所需数值
使用addObject()设置需要返回的值,addObject()有几个不同参数的方法,可以默认和指定返回对象的名字。
13.Springmvc 中系统如何分层 ?
系统分为表现层(UI):数据的展现,操作页面,请求转发。
业务层(服务层):封装业务处理逻辑
持久层(数据访问层):封装数据访问逻辑
各层之间的关系: 表示层通过接口调用业务层,业务层通过接口调用持久层,这样,当下一层发生变化改变,不影响上一层的数据。 MVC是一种表现层的架构
14. Springmvc 中拦截器如何使用
定义拦截器,实现HandlerInterceptor接口。接口中提供三个方法。
preHandle :进入 Handler方法之前执行,用于身份认证、身份授权,比如身份认证,如果认证通过表示当前用户没有登陆,需要此方法拦截不再向下执行
postHandle:进入Handler方法之后,返回modelAndView之前执行,应用场景从modelAndView出发:将公用的模型数据(比如菜单导航)在这里传到视图,也可以在这里统一指定视图
afterCompletion:执行Handler完成执行此方法,应用场景:统一异常处理,统一日志处理
拦截器配置:
针对HandlerMapping配置(不推荐):springmvc拦截器针对HandlerMapping进行拦截设置,如果在某个HandlerMapping中配置拦截,经过该 HandlerMapping映射成功的handler最终使用该 拦截器。(一般不推荐使用)
类似全局的拦截器:springmvc配置类似全局的拦截器,springmvc框架将配置的类似全局的拦截器注入到每个HandlerMapping中
15. 介绍一下Spring的事务管理
事务就是对一系列的数据库操作(比如插入多条数据)进行统一的提交或回滚操作,如果插入成功,那么一起成功,如果中间有一条出现异常,那么回滚之前的所有操作。
这样可以防止出现脏数据,防止数据库数据出现问题。 开发中为了避免这种情况一般都会进行事务管理。Spring中也有自己的事务管理机制,一般是使用TransactionMananger进行管理,可以通过Spring的注入来完成此功能。
sping的事务管理的两种方式:
1、编程式(粒度是到代码块级别);
编程式主要使用transactionTemplate;手动编程管理事务
2、声明式(粒度是到方法级别);
通过AOP实现, 其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。声明式事务最大的优点就是不需要通过编程的方式管理事务,这样就不需要在业务逻辑代码中掺杂事务管理的代码,只需在配置文件中做相关的事务规则声明(或通过基于@Transactional注解的方式),便可以将事务规则应用到业务逻辑中。
16. spring中的BeanFactory与ApplicationContext的作用有哪些?
Spring 通过一个配置文件来描述 Bean 及 Bean 之间的依赖关系,利用 Java 的反射功能实例化 Bean 并建立 Bean 之间的依赖关系 。Sprig 的 IoC 容器在完成这些底层工作的基础上,还提供了 Bean 实例缓存 、 生命周期管理 、Bean 实例代理 、 事件发布 、 资源装载等高级服务 。
Spring 提供了两种类型的 IOC 容器实现.
BeanFactory: IOC 容器的基本实现.
ApplicationContext: 提供了更多的高级特性. 是 BeanFactory 的子接口.
Bean 工厂( com.springframework.beans.factory.BeanFactory )是 Spring 框架中最核心的接口,它提供了高级 IoC 的配置机制 。BeanFactory 使管理不同类型的 Java 对象成为可能。而应用上下文( com.springframework.context.ApplicationContext )建立在 BeanFactory 基础之上,提供了更多面向应用的功能,它提供了国际化支持和框架事件体系,更易于创建实际应用 。
我们一般称 BeanFactory 为 IoC 容器,而称 ApplicationContext 为应用上下文或 Spring 容器 。
17. 你对Spring框架的理解,Spring框架有哪些模块?
Spring是一个轻量级的IoC和AOP容器框架,是为Java应用程序提供基础性服务的一套框架,目的是用于简化企业应用程序的开发,它使得开发者只需要关心业务需求。
Spring,一种用来简化企业应用级开发的一种开源框架。
简化开发:它对常用的API做了封装,比如对JDBC的封装,使用Spring JDBC访问数据库,就不需要考虑如何获取连接和关闭的问题。
解耦:Spring帮我们管理软件之间的依赖关系,这样对象之间的耦合性就降低了,这样的维护性就得到了提高。
集成其它框架:方便扩展和优化其功能,例如和Mybatis的集成等。
Spring框架是按照设计模式精心打造的,这使得我们在开发环境中,能方便的使用框架,不用考虑后台是怎么进行的。
Spring容器是Spring框架中一个核心的模块,用来管理对象的创建,销毁和初始化等操作,以及对象之间的依赖关系等。
主要包括以下七个模块:
Spring Context:提供框架式的Bean访问方式,以及企业级功能(JNDI、定时任务等);
Spring Core:核心类库,所有功能都依赖于该类库,提供IOC和DI服务;
Spring AOP:AOP服务;
Spring Web:提供了基本的面向Web的综合特性,提供对常见框架如Struts2的支持,Spring能够管理这些框架,将Spring的资源注入给框架,也能在这些框架的前后插入拦截器;
Spring MVC:提供面向Web应用的Model-View-Controller,即MVC实现;
Spring DAO:对JDBC的抽象封装,简化了数据访问异常的处理,并能统一管理JDBC事务;
Spring ORM:对现有的ORM框架的支持。
18. 什么是控制反转(IOC),什么是依赖注入(DI)?
IOC:就是对象之间的依赖关系由容器来创建,对象之间的关系本来是由我们开发者自己创建和维护的,在我们使用Spring框架后,对象之间的关系由容器来创建和维护,将开发者做的事让容器做,这就是控制反转。BeanFactory接口是Spring Ioc容器的核心接口。
DI:我们在使用Spring容器的时候,容器通过调用set方法或者是构造器来建立对象之间的依赖关系。
控制反转是目标,依赖注入是我们实现控制反转的一种手段。
19. Spring Bean的生命周期?
Spring作为当前Java最流行、最强大的轻量级框架,受到了程序员的热烈欢迎。准确的了解Spring Bean的生命周期是非常必要的。我们通常使用ApplicationContext作为Spring容器。这里,我们讲的也是 ApplicationContext中Bean的生命周期。而实际上BeanFactory也是差不多的,只不过处理器需要手动注册。
简单来说,Spring Bean的生命周期只有四个阶段:实例化 Instantiation --> 属性赋值 Populate --> 初始化 Initialization --> 销毁 Destruction
但具体来说,Spring Bean的生命周期包含下图的流程:
(1)实例化Bean
对于BeanFactory容器,当客户向容器请求一个尚未初始化的bean时,或初始化bean的时候需要注入另一个尚未初始化的依赖时,容器就会调用createBean进行实例化。
对于ApplicationContext容器,当容器启动结束后,通过获取BeanDefinition对象中的信息,实例化所有的bean。
(2)设置对象属性(依赖注入)
实例化后的对象被封装在BeanWrapper对象中,紧接着,Spring根据BeanDefinition中的信息 以及 通过BeanWrapper提供的设置属性的接口完成属性设置与依赖注入。
(3)处理Aware接口
Spring会检测该对象是否实现了xxxAware接口,通过Aware类型的接口,可以让我们拿到Spring容器的一些资源:
①如果这个Bean实现了BeanNameAware接口,会调用它实现的setBeanName(String beanId)方法,传入Bean的名字;
②如果这个Bean实现了BeanClassLoaderAware接口,调用setBeanClassLoader()方法,传入ClassLoader对象的实例。
②如果这个Bean实现了BeanFactoryAware接口,会调用它实现的setBeanFactory()方法,传递的是Spring工厂自身。
③如果这个Bean实现了ApplicationContextAware接口,会调用setApplicationContext(ApplicationContext)方法,传入Spring上下文。
(4)BeanPostProcessor前置处理
如果想对Bean进行一些自定义的前置处理,那么可以让Bean实现了BeanPostProcessor接口,那将会调用postProcessBeforeInitialization(Object obj, String s)方法。
(5)InitializingBean
如果Bean实现了InitializingBean接口,执行afeterPropertiesSet()方法。
(6)init-method
如果Bean在Spring配置文件中配置了 init-method 属性,则会自动调用其配置的初始化方法。
(7)BeanPostProcessor后置处理
如果这个Bean实现了BeanPostProcessor接口,将会调用postProcessAfterInitialization(Object obj, String s)方法;由于这个方法是在Bean初始化结束时调用的,所以可以被应用于内存或缓存技术;
以上几个步骤完成后,Bean就已经被正确创建了,之后就可以使用这个Bean了。
(8)DisposableBean
当Bean不再需要时,会经过清理阶段,如果Bean实现了DisposableBean这个接口,会调用其实现的destroy()方法。
(9)destroy-method
最后,如果这个Bean的Spring配置中配置了destroy-method属性,会自动调用其配置的销毁方法。
20. Spring框架中都用到了哪些设计模式?
单例模式 : Spring 中的 Bean 默认都是单例的。
工厂模式 : Spring使用工厂模式通过 BeanFactory、ApplicationContext 创建 bean 对象。
模板方法模式 : Spring 中 jdbcTemplate、hibernateTemplate 等以 Template 结尾的对数据库操作的类,它们就使用到了模板模式。
代理模式 : Spring AOP 功能的实现。
观察者模式: Spring 事件驱动模型就是观察者模式很经典的一个应用。
适配器模式 :Spring AOP 的增强或通知(Advice)使用到了适配器模式、spring MVC 中也是用到了适配器模式适配Controller。
装饰者模式 : 我们的项目需要连接多个数据库,而且不同的客户在每次访问中根据需要会去访问不同的数据库。这种模式让我们可以根据客户的需求能够动态切换不同的数据源。
21. Spring AOP(面向切面)编程的原理?
AOP面向切面编程,它是一种思想。它就是针对业务处理过程中的切面进行提取,以达到优化代码的目的,减少重复代码的目的。 就比如,在编写业务逻辑代码的时候,我们习惯性的都要写:日志记录,事物控制,以及权限控制等,每一个子模块都要写这些代码,代码明显存在重复。这时候,我们运用面向切面的编程思想,采用横切技术,将代码中重复的部分,不影响主业务逻辑的部分抽取出来,放在某个地方进行集中式的管理,调用。 形成日志切面,事物控制切面,权限控制切面。 这样,我们就只需要关系业务的逻辑处理,即提高了工作的效率,又使得代码变的简洁优雅。这就是面向切面的编程思想,它是面向对象编程思想的一种扩展。
AOP的使用场景: 缓存、权限管理、内容传递、错误处理、懒加载、记录跟踪、优化、校准、调试、持久化、资源池、同步管理、事物控制等。 AOP的相关概念: 切面(Aspect) 连接点(JoinPoint) 通知(Advice) 切入点(Pointcut) 代理(Proxy): 织入(WeaVing)
Spring AOP的编程原理? 代理机制JDK的动态代理:只能用于实现了接口的类产生代理。 Cglib代理:针对没有实现接口的类产生代理,应用的是底层的字节码增强技术,生成当前类的子类对象。
(1)连接点(Join point):指程序运行过程中所执行的方法。在Spring AOP中,一个连接点总代表一个方法的执行。
(2)切面(Aspect):被抽取出来的公共模块,可以用来会横切多个对象。Aspect切面可以看成 Pointcut切点 和 Advice通知 的结合,一个切面可以由多个切点和通知组成。
在Spring AOP中,切面可以在类上使用 @AspectJ 注解来实现。
(3)切点(Pointcut):切点用于定义 要对哪些Join point进行拦截。
切点分为execution方式和annotation方式。execution方式可以用路径表达式指定对哪些方法拦截,比如指定拦截add*、search*。annotation方式可以指定被哪些注解修饰的代码进行拦截。
(4)通知(Advice):指要在连接点(Join Point)上执行的动作,即增强的逻辑,比如权限校验和、日志记录等。通知有各种类型,包括Around、Before、After、After returning、After throwing。
(5)目标对象(Target):包含连接点的对象,也称作被通知(Advice)的对象。 由于Spring AOP是通过动态代理实现的,所以这个对象永远是一个代理对象。
(6)织入(Weaving):通过动态代理,在目标对象(Target)的方法(即连接点Join point)中执行增强逻辑(Advice)的过程。
(7)引入(Introduction):添加额外的方法或者字段到被通知的类。Spring允许引入新的接口(以及对应的实现)到任何被代理的对象。例如,你可以使用一个引入来使bean实现 IsModified 接口,以便简化缓存机制。
几个概念的关系图可以参考下图:
AOP实现的关键在于代理模式,AOP代理主要分为静态代理和动态代理。静态代理的代表为AspectJ;动态代理则以Spring AOP为代表。
(1)AspectJ是静态代理,也称为编译时增强,AOP框架会在编译阶段生成AOP代理类,并将AspectJ(切面)织入到Java字节码中,运行的时候就是增强之后的AOP对象。
(2)Spring AOP使用的动态代理,所谓的动态代理就是说AOP框架不会去修改字节码,而是每次运行时在内存中临时为方法生成一个AOP对象,这个AOP对象包含了目标对象的全部方法,并且在特定的切点做了增强处理,并回调原对象的方法。
Spring AOP中的动态代理主要有两种方式,JDK动态代理和CGLIB动态代理:
① JDK动态代理只提供接口的代理,不支持类的代理,要求被代理类实现接口。JDK动态代理的核心是InvocationHandler接口和Proxy类,在获取代理对象时,使用Proxy类来动态创建目标类的代理类(即最终真正的代理类,这个类继承自Proxy并实现了我们定义的接口),当代理对象调用真实对象的方法时, InvocationHandler 通过invoke()方法反射来调用目标类中的代码,动态地将横切逻辑和业务编织在一起;
InvocationHandler 的 invoke(Object proxy,Method method,Object[] args):proxy是最终生成的代理对象; method 是被代理目标实例的某个具体方法;args 是被代理目标实例某个方法的具体入参, 在方法反射调用时使用。
② 如果被代理类没有实现接口,那么Spring AOP会选择使用CGLIB来动态代理目标类。CGLIB(Code Generation Library),是一个代码生成的类库,可以在运行时动态的生成指定类的一个子类对象,并覆盖其中特定方法并添加增强代码,从而实现AOP。CGLIB是通过继承的方式做的动态代理,因此如果某个类被标记为final,那么它是无法使用CGLIB做动态代理的。
(3)静态代理与动态代理区别在于生成AOP代理对象的时机不同,相对来说AspectJ的静态代理方式具有更好的性能,但是AspectJ需要特定的编译器进行处理,而Spring AOP则无需特定的编译器处理。
IoC让相互协作的组件保持松散的耦合,而AOP编程允许你把遍布于应用各层的功能分离出来形成可重用的功能组件。
22.WebService如何与客户端交互
① webServices通过SOAP协议进行参数的接收与返回值的传递。
② SOAP协议在web上提供软件服务,使用WSDL文件进行说明,通过UDDI进行注册
③ WSDL文件是一个XML文档,用于说明一组SOAP消息以及如何交换这些信息,大多数情况下由软件自动生成和使用
④ XML是一种扩展型可标记语言,面向短期临时数据和万维网络。
⑤ UDDI是一个主要针对web服务供应商和使用者的项目,在用户能够调用web服务之前,必须确定这个服务包含哪些商务方法,找到被调用的接口定义,还要服务端来编制软件;UDDI是一种根据描述文章来引导系统查找响应服务的机制,UDDI利用SOAP消息机制来发布、编译、浏览及查找注册信息,它采用XML格式来封装各种不同类型的数据,并且发送到注册中心来返回需要的数据。
23. 拦截器和过滤器的区别
① 拦截器inteceptor是基于java的反射机制实现的;
过滤器Filter是基于函数回调实现(filter接口中的doFilter方法是回调函数实现的)
② 拦截器不依赖于servlet容器;
过滤器filter依赖servlet,没有servlet无法回调doFilter
③ 拦截器只能对action请求起作用;
而filter可以对所有请求起作用,filter过滤范围比拦截器大
④ 拦截器可以访问action上下文,值栈里的对象;
而过滤器filter不能;
⑤ 在action的生命周期中,拦截器可以多次被调用;
而过滤器只能在容器初始化时被调用一次;
⑥ 拦截器可以获取IOC容器中的各个bean,而过滤器不行;
24. Spring MVC异常处理
1.使用@ExceptionHandler注解。
public class AccountController {
@ExceptionHandler
public void handleException() {}
}
@ExceptionHandler是Controller级别的,不是整个应用程序全局有效。给每个controller添加对应的@ExceptionHandler方法会很繁琐。可以让所有Controller类继承BaseController类,在BaseController类里面添加@ExceptionHandler修饰的方法进行异常处理。
2. 使用HandlerExceptionResolver可以实现一个统一的异常处理机制。Spring提供了以下HandlerExceptionResolver可以使用:
ExceptionHandlerExceptionResolver是@ExceptionHandler机制工作的核心组件。
DefaultHandlerExceptionResolver用于将标准的Spring异常解析为相应的http状态码。
ResponseStatusExceptionResolver主要用于把修饰自定义异常的@ResponseStatus注解映射对应异常到相应的http状态码。
SimpleMappingExceptionResolver和AnnotationMethodHandlerExceptionResolver
自定义 HandlerExceptionResolver可以返回一个ModelAndView对象,可以设置需要的任何内容。
3. 新的@ControllerAdvice提供了一个全局的@ExceptionHandler 异常处理机制。
@ControllerAdvice
public class ExceptionHandler {
@ExceptionHandler(Exception.class)
public Result handleException(Exception e) {
// todo
}
}
@ControllerAdvice允许把分散在多个Controller的@ExceptionHandler合并到单个全局错误处理组件中。
25. Spring MVC进行传值的方式有哪些?
(1)、页面传值到控制器有三种方式:
使用Request传值的特点:直接,但是不能自动进行类型转换。
通过属性传值的特点:
第一、变量名必须和表单组件的name值相同
第二、可以实现类型转换
第三、进行类型转换时可能会出现异常
使用Bean对象传值的特点:
第一、如果前端提交数据过多,建议使用此方式
第二、把表单组件的name属性值封装到Bean类中,
第三、方法的参数传递封装类型的对象即可
(2)、控制器传值到页面有三种方式:
使用Request和Session对象
使用ModelAndView传值的特点:
第一、可以在ModelAndView构造方法中设置一个Map对象
第二、Map对象经过框架处理后,会把key-value设置到Request对象中。
ModelMap传值的特点:
第一、ModelMap是框架提供的Map集合
第二、ModelMap同样被框架设置到Request对象中。
26. Spring MVC如何进行乱码处理?
对于POST乱码,在web.xml文件中添加POST乱码过滤器——CharacterEncodingFilter
对于GET请求中文参数出现乱码的情况,解决方案:
(1)、修改Tomcat配置文件,添加编码与工作编码一致
<Connector URLEncoding="utf-8" connectionTimeout="2000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>
(2)、对参数进行重新编码
String userName=new String(request.getParamter("username".getBytes("ISO8859-1","utf-8")))
ISO8859-1是Tomcat默认编码,需要将Tomcat编码后的内容按utf-8编码。
26. Spring MVC拦截器的三个方法的执行时机是什么?
当两个拦截器都实现放行操作时,顺序为preHanle1、preHandle2、postHandle2、postHandle1、afterCompletion2、afterCompletion1;
当第一个拦截器preHandle返回false,也就是对其进行拦截时,第二个拦截器是完全不执行的,第一个拦截器只执行preHandle部分。
当第一个拦截器preHandle返回True,第二个拦截器preHandle返回false,顺序为preHandle1、preHandle2、afterCompletion1
27. 什么是ContextLoaderListener,它的作用是什么?
ContextLoaderListener是一个监听器,这有助于引导Spring MVC的。顾名思义它加载并创建ApplicationContext,因此不必编写显式代码来创建它。应用程序上下文是Spring bean离开的地方。对于Web应用程序,有一个名为WebAppliationContext的子类。
ContextLoaderListener还将ApplicationContext的生命周期与ServletContext的生命周期联系起来。这可以使用getServletContext()方法从WebApplicationContext获取ServletContext。
28. 传入请求如何映射到控制器和方法?
有时也会问这个问题DispatcherServlet如何知道哪个Controller应该处理请求?
Spring使用处理程序映射将控制器与请求相关联,两个常用的处理程序映射是BeanNameUrlHandlerMapping和SimpleUrlHandlerMapping。
在BeanNameUrlHandlerMapping中,当请求url与bean的名称匹配时,bean定义中的类是将处理请求的控制器。
另一方面,在SimpleUrlHandlerMapping中,映射更明确。可以指定URL的数量,并且每个URL可以与控制器显式关联。
顺便说一句,如果你使用注释来配置Spring MVC,那么应该使用@RequestMapping注释将传入请求映射到控制器和处理程序方法。
还可以通过URI路径,查询参数,请求的HTTP方法以及请求中存在的HTTP标头配置@RequestMapping批注。
29. @RequestParam用于什么?
@RequestParam是一个Spring MVC注释,其被用于提取从URL中控制器的处理程序方法请求参数或查询参数,如下所示:
public String personDetail(@RequestParam(“id”)long id){
....
return“personDetails”;
}
@RequestParam注释也支持数据类型转换,例如这里可以看到一个String被自动转换为long,但它也可能导致一个异常,如果查询参数不存在或类型不匹配的情况下 还可以使用requried = false使参数成为可选参数,例如@RequestParam(value =“id”,required = false)
30. SpringBoot、SpringMVC、Spring有什么区别?
Springboot是简化配置,将mybatis中的配置数据源,主配置文件等配置,spring、springMVC的配置文件都用springboot的yml文件配置,极大的简化了配置,使项目可以快速的启动起来。SpringMVC是通过(model),V(view),C(controller)的结构进行分层,从而实现前后端分离的效果,然后通过前端控制器(DispatcherServlet),处理器映射器(HandlerMapping),处理器适配器(HandlerAdapter),视图解析器(ViewResolver),将各层有机的组织起来,使每个人都有不同的分工从而加快了开发的效率。
Spring是由Aop面向切面和IOC控制翻转(又称作DI依赖注入),面向切面是把主方法和其他的一些无关的方法分离开来,从而达到降低耦合的效果,控制翻转是指将原先是由new创建的对象,各个类之间的依赖较强,将创建对象的权利交托给ioc容器后,由ioc容器来创建对象,使耦合度减小,提高了效率。
31. SpringMVC接口解释
(1)DispatcherServlet接口:
Spring提供的前端控制器,所有的请求都有经过它来统一分发。在DispatcherServlet将请求分发给Spring Controller之前,需要借助于Spring提供的HandlerMapping定位到具体的Controller。
(2)HandlerMapping接口:
能够完成客户请求到Controller映射。
(3)Controller接口:
需要为并发用户处理上述请求,因此实现Controller接口时,必须保证线程安全并且可重用。
Controller将处理用户请求,这和Struts Action扮演的角色是一致的。一旦Controller处理完用户请求,则返回ModelAndView对象给DispatcherServlet前端控制器,ModelAndView中包含了模型(Model)和视图(View)。
从宏观角度考虑,DispatcherServlet是整个Web应用的控制器;从微观考虑,Controller是单个Http请求处理过程中的控制器,而ModelAndView是Http请求过程中返回的模型(Model)和视图(View)。
(4)ViewResolver接口:
Spring提供的视图解析器(ViewResolver)在Web应用中查找View对象,从而将相应结果渲染给客户。