1、说一下 spring mvc 运行流程?
- spring mvc 先将请求发送给 DispatcherServlet。
- DispatcherServlet 查询一个或多个 HandlerMapping,找到处理请求的 Controller。 DispatcherServlet 再把请求提交到对应的 Controller。
- Controller 进行业务逻辑处理后,会返回一个ModelAndView。
- Dispathcher 查询一个或多个 ViewResolver 视图解析器,找到 ModelAndView 对象指定的视图对象。 视图对象负责渲染返回给客户端。
2、说一下 spring 的事务隔离?
spring 有五大隔离级别,默认值为 ISOLATION_DEFAULT(使用数据库的设置),其他四个隔离级别和数据库的隔离级别一致:
- ISOLATION_DEFAULT:用底层数据库的设置隔离级别,数据库设置的是什么我就用什么;
- ISOLATIONREADUNCOMMITTED:未提交读,最低隔离级别、事务未提交前,就可被其他事务读取(会出现幻读、脏读、不可重复读);
- ISOLATIONREADCOMMITTED:提交读,一个事务提交后才能被其他事务读取到(会造成幻读、不可重复读),SQL server 的默认级别;
- ISOLATIONREPEATABLEREAD:可重复读,保证多次读取同一个数据时,其值都和事务开始时候的内容是一致,禁止读取到别的事务未提交的数据(会造成幻读),MySQL 的默认级别;
- ISOLATION_SERIALIZABLE:序列化,代价最高最可靠的隔离级别,该隔离级别能防止脏读、不可重复读、幻读。 脏读 :表示一个事务能够读取另一个事务中还未提交的数据。比如,某个事务尝试插入记录 A,此时该事务还未提交,然后另一个事务尝试读取到了记录 A。 不可重复读 :是指在一个事务内,多次读同一数据。 幻读 :指同一个事务内多次查询返回的结果集不一样。比如同一个事务 A 第一次查询时候有 n 条记录,但是第二次同等条件下查询却有 n+1 条记录,这就好像产生了幻觉。发生幻读的原因也是另外一个事务新增或者删除或者修改了第一个事务结果集里面的数据,同一个记录的数据内容被修改了,所有数据行的记录就变多或者变少了。
3、spring 自动装配 bean 有哪些方式?
- no:默认值,表示没有自动装配,应使用显式 bean 引用进行装配。
- byName:它根据 bean 的名称注入对象依赖项。
- byType:它根据类型注入对象依赖项。 构造函数:通过构造函数来注入依赖项,需要设置大量的参数。
autodetect:容器首先通过构造函数使用 autowire 装配,如果不能,则通过 byType 自动装配。
4、spring 支持几种 bean 的作用域?
spring 支持 5 种作用域,如下:
- singleton:spring ioc 容器中只存在一个 bean 实例,bean 以单例模式存在,是系统默认值; prototype:每次从容器调用 bean 时都会创建一个新的示例,既每次 getBean()相当于执行 new Bean()操作;
- Web 环境下的作用域:
- request:每次 http 请求都会创建一个 bean;
- session:同一个 http session 共享一个 bean 实例;
- global-session:用于 portlet 容器,因为每个 portlet 有单独的 session,globalsession 提供一个全局性的 http session。
5、spring 中的 bean 是线程安全的吗?
spring 中的 bean 默认是单例模式,spring 框架并没有对单例 bean 进行多线程的封装处理。 实际上大部分时候 spring bean 无状态的(比如 dao 类),所有某种程度上来说 bean 也是安全的,但如果 bean 有状态的话(比如 view model 对象),那就要开发者自己去保证线程安全了,最简单的就是改变 bean 的作用域,把“singleton”变更为“prototype”,这样请求 bean 相当于 new Bean()了,所以就可以保证线程安全了。 有状态就是有数据存储功能。 无状态就是不会保存数据。
6、谈谈你对SpringIOC和DI的理解?
首先,SpringIOC,全称控制反转(InversionofControl)。 在传统的Java程序开发中,我们只能通过new关键字来创建对象,这种导致程序中对象的依赖关系比较复杂,耦合度较高。 而IOC的主要作用是实现了对象的管理,也就是我们把设计好的对象交给了IOC 容器控制,然后在需要用到目标对象的时候,直接从容器中去获取。 有了IOC容器来管理Bean以后,相当于把对象的创建和查找依赖对象的控制权交给了容器,这种设计理念使得对象与对象之间是一种松耦合状态,极大提升了程序的灵活性以及功能的复用性。 然后,DI表示依赖注入,也就是对于IOC容器中管理的Bean,如果Bean之间存在依赖关系,那么IOC容器需要自动实现依赖对象的实例注入,通常有三种方法来描述Bean之间的依赖关系。 接口注入 setter注入 构造器注入 另外,为了更加灵活的实现Bean实例的依赖注入,Spring还提供了@Resource和@Autowired这两个注解。 分别是根据bean的id和bean的类型来实现依赖注入。
7、Spring Cloud 如何实现服务的注册
服务注册的实现方式 Spring Cloud提供了几种服务注册的实现方式,包括:
Eureka:Netflix公司开源的、最为流行的一种服务注册中心;
Consul:由Hashicorp公司开发的一种服务发现组件,支持多数据中心;
ZooKeeper:由Apache项目开发的一种分布式协调框架。 Eureka的工作原理 注册中心 注册中心是一个基于REST的服务,主要实现服务注册、服务续约、服务下线以及查询功能。
Eureka Server接收服务实例的注册请求,并将服务实例信息存储在内存中(HashMap)。当Eureka Server收到服务实例的续约请求时,会更新服务实例在内存中的信息,避免服务实例过期失效。也可以通过URL获取注册中心中所有可用的服务。 服务实例 服务实例启动后会向Eureka Server发送注册请求,告知Eureka Server自己的地址(ip:port)、服务名、健康状态以及一些元数据。同时服务实例会以心跳的方式向Eureka Server发送服务续约请求,在规定时间内没有接收到续约请求,则视为服务实例失效。
8、Spring Boot如何解决跨域问题?
跨域是指在浏览器中,当一个网页的脚本试图去访问另一个网页的资源时,如果这两个网页的域名、协议或端口不一致,就会发生跨域问题。 JSONP(JSON with Padding):JSONP是一种利用script标签的src属性不受同源策略限制的特点来进行跨域数据传输的方法。通过动态创建script标签,并指定src属性为跨域请求的URL,服务器返回的数据会被包裹在回调函数中,通过执行回调函数来获取数据。 CORS(跨域资源共享):CORS是一种标准的跨域解决方案,它通过在服务器端设置响应头来允许指定的域名进行跨域访问。在服务器端设置Access-Control-Allow-Origin字段,指定允许的域名或通配符(*)来解决跨域问题。 代理服务器:可以在同源的情况下,设置一个代理服务器,将跨域请求转发到目标服务器,再将结果返回给浏览器。客户端通过访问同源的代理服务器来避免跨域问题。 WebSocket:WebSocket是一种全双工通信协议,不受同源策略的限制,可以在不同域名间进行跨域通信。 postMessage:使用HTML5中的postMessage方法,可以实现不同窗口(甚至不同域名)之间的跨域通信。 在Spring Boot项目中可以通过配置来解决跨域问题,在Spring Boot的配置类中添加一个跨域配置的Bean。
9、Spring Boot 核心配置文件
1、application.properties application.properties 是基于属性文件的配置格式,支持 key-value 形式的键值对。在 Spring Boot 中,可以在 application.properties 文件中配置各种应用程序属性,如端口号、数据库连接、日志级别等等。
2、application.yml application.yml 是基于 YAML 格式的配置文件,支持层级结构的配置形式,可以更加清晰地表达配置项之间的关系。与 application.properties 相比,application.yml 更易读、易维护,也更加灵活。
3、常用配置项 以下是一些常用的 Spring Boot 配置项: 服务器配置 server.port:应用程序监听的端口号,默认为 8080; server.servlet.context-path:应用程序的上下文路径,默认为空; server.tomcat.access-log-enabled:是否开启访问日志,默认为 false。
10、什么是Spring Boot Stater?
Spring Boot Starter是Spring Boot框架中的一个重要概念,它是一种可重用的模块,用于快速启动和配置Spring应用程序。Spring Boot Starter可以包含多个依赖项,这些依赖项可以自动配置和集成到应用程序中,从而简化了应用程序的开发和部署。Spring Boot Starter可以根据应用程序的需求进行选择和组合,使得应用程序的构建更加灵活和高效。
11、Spring支持的事务管理类型有哪些?你在项目中使用哪种方式?
答:Spring支持编程式事务管理和声明式事务管理。许多Spring框架的用户选择声明式事务管理,因为这种方式和应用程序的关联较少,因此更加符合轻量级容器的概念。声明式事务管理要优于编程式事务管理,尽管在灵活性方面它弱于编程式事务管理,因为编程式事务允许你通过代码控制业务。 事务分为全局事务和局部事务。全局事务由应用服务器管理,需要底层服务器JTA支持(如WebLogic、WildFly等)。局部事务和底层采用的持久化方案有关,例如使用JDBC进行持久化时,需要使用Connetion对象来操作事务;而采用Hibernate进行持久化时,需要使用Session对象来操作事务。
12、Spring Bean 生命周期的执行流程
- 创建前准备阶段;
- 创建实例阶段;
- 依赖注入阶段;
- 容器缓存阶段;
- 销毁实例阶段;
- REQUIRED:默认的 Spring 事物传播级别,如果当前存在事务,则加入这个事
- REQUIRE_NEW:不管是否存在事务,都会新开一个事务,新老事务相互独立。
- NESTED:如果当前存在事务,则嵌套在当前事务中执行。如果当前没有事务,
- SUPPORTS:表示支持当前事务,如果当前不存在事务,以非事务的方式执行。
- NOT_SUPPORTED:表示以非事务的方式来运行,如果当前存在事务,则把当
- MANDATORY:强制事务执行,若当前不存在事务,则抛出异常.
- NEVER:以非事务的方式执行,如果当前存在事务,则抛出异常。