Spring基础知识

一、Spring的核心是什么?

  • spring是一个开源框架,也是一个生态。
  • spring是为了简化企业开发而生的,使得开发变得更加优雅和简洁。spring是一个IOC和AOP的容器框架。
  • lOC:控制反转(原来对象需要我们自己创建,现在用容器控制,包括对象注入等)
  • IOC是一种实现思想,DI是一种具体的实现方式
  • AOP:面向切面编程
  • 容器:包含并管理应用对象的生命周期,就好比用桶装水一样,spring就是桶,而对象就是水

二、使用spring的优势?

  1. Spring通过DI、AOP和消除样板式代码来简化企业级Java开发
  2. Spring框架之外还存在一个构建在核心框架之上的庞大生态圈,它将Spring扩展到不同的领域,如Web服务、REST、移动开发以及NoSQL
  3. 低侵入式设计,代码的污染极低
  4. 独立于各种应用服务器,基于Spring框架的应用,可以真正实现Write Once,Run Anywhere的承诺
  5. Spring的lOC容器降低了业务对象替换的复杂性,提高了组件之间的解耦
  6. Spring的AOP支持允许将一些通用任务如安全、事务、日志等进行集中式处理,从而提供了更好的复用
  7. Spring的ORM和DAO提供了与第三方持久层框架的的良好整合,并简化了底层的数据库访问
  8. Spring的高度开放性,并不强制应用完全依赖于Spring,开发者可自由选用Spring框架的部分或全部

三、spring的事务传播机制是什么?

多个事务方法相互调用时,事务如何在这些方法之间进行传播,spring中提供了7种不同的传播特性,来保证事务的正常执行:

  • REQUIRED默认的传播特性,如果当前没有事务,则新建一个事务,如果当前存在事务,则加入这个事务
  • SUPPORTS:当前存在事务,则加入当前事务,如果当前没有事务,则以非事务的方式执行
  • MANDATORY:当前存在事务,则加入当前事务,如果当前事务不存在,则抛出异常REQUIRED_NEW:创建一个新事务,如果存在当前事务,则挂起改事务
  • NOT_SUPPORTED:以非事务方式执行,如果存在当前事务,则挂起当前事务
  • NEVER:不使用事务,如果当前事务存在,则抛出异常
  • NESTED:如果当前事务存在,则在嵌套事务中执行,否则REQUIRED的操作一样

1、NESTED和REQUIRED_NEW的区别:

REQUIRED_NEW是新建一个事务并且新开始的这个事务与原有事务无关,而NESTED则是当前存在事务时会开启一个嵌套事务,在NESTED情况下,父事务回滚时,子事务也会回滚,而REQUIRED_NEW情况下,原有事务回滚,不会影响新开启的事务

2、NESTED和REQUIRED的区别:

REQUIRED情况下,调用方存在事务时,则被调用方和调用方使用同一个事务,那么被调用方出现异常时,由于共用一个事务,所以无论是否catch异常,事务都会回滚,而在NESTED情况下,被调用方发生异常时,调用方可以catch其异常,这样只有子事务回滚,父事务不会回滚。

四、spring.springmvc、springboot的区别是什么?

1、spring和springMvc:

  1. spring是一个一站式的轻量级的java开发框架,核心是控制反转(IOC)和面向切面(AOP),针对于开发的WEB层(springMvc)、业务层(lOC)、持久层(jdbcTemplate)等都提供了多种配置解决方案;
  2. springMVC是spring基础之上的一个MVC框架,主要处理web开发的路径映射和视图渲染,属于spring框架中WEB层开发的一部分;

2、springMVC和springBoot:

  1. springMVC属于一个企业WEB开发的MVC框架,涵盖面包括前端视图开发、文件配置、后台接口逻辑开发等,XML、config等配置相对比较繁琐复杂;
  2. springBoot框架相对于springMVC框架来说,更专注于开发微服务后台接口,不开发前端视图,同时遵循默认优于配置,简化了插件配置流程,不需要配置xml,相对springmvc,大大简化了配置流程;

3、总结:

  1. Spring框架就像一个家族,有众多衍生产品例如 boot、security、jpa等等。但他们的基础都是Spring的ioc、 aop等。 ioc提供了依赖注入的容器aop解决了面向横切面编程,然后在此两者的基础上实现了其他延伸产品的高级功能;
  2. springMVC主要解决WEB开发的问题,是基于Servlet的一个MVC框架,通过XML配置
    统一开发前端视图和后端逻辑;
  3. 由于Spring的配置非常复杂,各种XML、JavaConfig、servlet处理起来比较繁琐,为了简化开发者的使用,从而创造性地推出了springBoot框架,默认优于配置,简化了springMVC的配置流程;但区别于springMVC的是,springBoot专注于单体微服务接口开发,和前端解耦,虽然springBoot也可以做成springMVC前后台一起开发,但是这就有点不符合springBoot框架的初衷了;

五、spring boot自动装配原理

启动类的@SpringBootApplication注解由@SpringBootConfiguration,@EnableAutoConfiguration,@ComponentScan三个注解组成,三个注解共同完成自动装配

  • @SpringBootConfiguration 注解标记启动类为配置类
  • @ComponentScan 注解实现启动时扫描启动类所在的包以及子包下所有标记为bean的类由IOC容器注册为bean
  • @EnableAutoConfiguration通过 @Import 注解导入 AutoConfigurationImportSelector类,然后通过AutoConfigurationImportSelector 类的 selectImports 方法去读取需要被自动装配的组件依赖下的spring.factories文件配置的组件的类全名,并按照一定的规则过滤掉不符合要求的组件的类全名,将剩余读取到的各个组件的类全名集合返回给IOC容器并将这些组件注册为bean

六、springmvc工作流程是什么?

当发起请求时被前置的控制器拦截到请求,根据请求参数生成代理请求,找到请求对应的实际控制器控制器处理请求创建数据模型访问数据库将模型响应给中心控制器控制器使用模型与视图渲染视图结果,将结果返回给中心控制器,再将结果返回给请求者

  1. DispatcherServlet表示前置控制器,是整个SpringMVC的控制中心。用户发出请求,DispatcherServlet接收请求并拦截请求。
  2. HandlerMapping为处理器映射。DispatcherServlet调用HandlerMapping,HandlerMapping根据请求url查找Handler。
  3. 返回处理器执行链,根据url查找控制器,并且将解析后的信息传递给DispatcherServiet
  4. HandlerAdapter表示处理器适配器,其按照特定的规则去执行Handler。
  5. 执行handler找到具体的处理器
  6. Controller将具体的执行信息返回给HandlerAdapter,如ModelAndView。
  7. HandlerAdapter将视图逻辑名或模型传递给DispatcherServlet。
  8. DispatcherServlet调用视图解析器(ViewResolver)来解析HandlerAdapter传递的逻辑视图名。
  9. 视图解析器将解析的逻辑视图名传给DispatcherServlet。
  10. DispatcherServlet根据视图解析器解析的视图结果,调用具体的视图,进行试图渲染
  11. 将响应数据返回给客户端

七、springmvc的九大组件有哪些?

  1. HandlerMapping
    根据request找到相应的处理器。因为Handler (Controller)有两种形式,一种是基于类的Handler,另一种是基于Method的Handler(也就是我们常用的)
  2. HandlerAdapter
    调用Handler的适配器。如果把Handler (Controller)当做工具的话,那么HandlerAdapter就相当于干活的工人
  3. HandlerExceptionResolver
    对异常的处理
  4. ViewResolver
    用来将String类型的视图名和Locale解析为View类型的视图
  5. RequestToViewNameTranslator
    有的Handler (Controller)处理完后没有设置返回类型,比如是void方法,这是就需要从request中获取viewName
  6. LocaleResolver
    从request中解析出Locale。Locale表示一个区域,比如zh-cn,对不同的区域的用户,显示不同的结果,这就是i18n (SpringMVC中有具体的拦截器LocaleChangelnterceptor)
  7. ThemeResolver
    主题解析,这种类似于我们手机更换主题,不同的UI,css等
  8. MultipartResolver
    处理上传请求,将普通的request封装成MultipartHttpservletRequest
  9. FlashMapManager
    用于管理FlashMap,FlashMap用于在redirect重定向中传递参数

八、Spring框架中的单例Bean是线程安全的么

  • Spring中的Bean对象默认是单例的,框架并没有对bean进行多线程的封装处理
  • 如果Bean是有状态的,那么就需要开发人员自己来保证线程安全的保证,最简单的办法就是改变bean的作用域把singleton改成prototype,这样每次请求bean对象就相当于是创建新的对象来保证线程的安全
  • 有状态就是由数据存储的功能
  • 无状态就是不会存储数据,你想一下,我们的controller,service和dao本身并不是线程安全的,只是调用里面的方法,而且多线程调用一个实例的方法,会在内存中复制遍历,这是自己线程的工作内存,是最安全的。
  • 因此在进行使用的时候,不要在bean中声明任何有状态的实例变量或者类变量,如果必须如此,也推荐大家使用ThreadLocal把变量变成线程私有,如果bean的实例变量或者类变量需要在多个线程之间共享,那么就只能使用synchronized,lock,cas等这些实现线程同步的方法了。

九、spring框架中使用了哪些设计模式及应用场景

  1. 工厂模式,在各种BeanFactory以及ApplicationContext创建中都用到了
  2. 模版模式,在各种BeanFactory以及ApplicationContext实现中也都用到了
  3. 代理模式,Spring AOP利用了AspectJ AOP实现的! AspectJ AOP的底层用了动态代理
  4. 策略模式,加载资源文件的方式,使用了不同的方法,比如: ClassPathResourece,FileSystemResource,ServletContextResource,UrlResource但他们都有共同的接口Resource在Aop的实现中,采用了两种不同的方式,JDK动态代理和CGLIB代理
  5. 单例模式,比如在创建bean的时候。
  6. 观察者模式, spring中的ApplicationEvent,ApplicationListener,ApplicationEventPublisher
  7. 适配器模式,MethodBeforeAdviceAdapter,ThrowsAdviceAdapter,AfterReturningAdapter
  8. 装饰者模式,源码中类型带Wrapper或者Decorator的都是

十、spring事务的隔离级别有哪些?

spring中的事务隔离级别就是数据库的隔离级别,有以下几种:

  • read uncommitted(未提交读)
  • read committed(提交读取)
  • repeatable read(重复读)
  • serializable(序列化)

在进行配置的时候,如果数据库和spring代码中的隔离级别不同,那么以spring的配置为主,需要与MySQL的事务隔离一起回答。

十一、spring事务的实现方式原理是什么?

  • 在使用Spring框架的时候,可以有两种事务的实现方式,一种是编程式事务,有用户自己通过代码来控制事务的处理逻辑,还有一种是声明式事务,通过@Transactional注解来实现。
  • 其实事务的操作本来应该是由数据库来进行控制,但是为了方便用户进行业务逻辑的操作,spring对事务功能进行了扩展实现,一般我们很少会用编程式事务,更多的是通过添加@Transactional注解来进行实现,当添加此注解之后事务的自动功能就会关闭,由spring框架来帮助进行控制
  • 其实事务操作是AOP的一个核心体现,当一个方法添加@Transactional注解之后,spring会基于这个类生成一个代理对象,会将这个代理对象作为bean,当使用这个代理对象的方法的时候,如果有事务处理,那么会先把事务的自动提交给关系,然后去执行具体的业务逻辑,如果执行逻辑没有出现异常,那么代理逻辑就会直接提交,如果出现任何异常情况,那么直接进行回滚操作,当然用户可以控制对哪些异常进行回滚操作。

十二、spring事务什么时候会失效?

  1. bean对象没有被spring容器管理
  2. 方法的访问修饰符不是public
  3. 自身调用问题
  4. 数据源没有配置事务管理器
  5. 数据库不支持事务
  6. 异常被捕获
  7. 异常类型错误或者配置错误

十三、Spring是如何简化开发的(IOC和AOP)?

  • 基于POJO的轻量级和最小侵入性编程
  • 通过依赖注入和面向接口实现松耦合
  • 基于切面和惯例进行声明式编程
  • 通过切面和模板减少样板式代码

十四、spring支持的bean作用域有哪些?

  1. singleton
    使用该属性定义Bean时,IOC容器仅创建一个Bean实例,IOC容器每次返回的是同一个Bean实例。
  2. prototype
    使用该属性定义Bean时,IOC容器可以创建多个Bean实例,每次返回的都是一个新的实例。
  3. request
    该属性仅对HTTP请求产生作用,使用该属性定义Bean时,每次HTTP请求都会创建一个新的Bean,适用于WebApplicationContext环境。
  4. session
    该属性仅用于HTTP Session,同一个Session共享一个Bean实例。不同Session使用不同的实例。
  5. global-session
    该属性仅用于HTTP Session,同session作用域不同的是,所有的Session共享一个Bean实例。

十五、Spring bean生命周期(简单说明)

Bean的生命周期概括起来就是4个阶段:

  1. 实例化(Instantiation)
  2. 属性赋值(Populate)
  3. 初始化(Initialization)
  4. 销毁(Destruction)

十六、如何理解springboot中的starter?

  • 使用spring+springmvc框架进行开发的时候,如果需要引入mybatis框架,那么需要在xml中定义需要的bean对象,这个过程很明显是很麻烦的,如果需要引入额外的其他组件,那么也需要进行复杂的配置,因此在springboot中引入了starter
  • starter就是一个jar包,写一个@Configuration的配置类,将这些bean定义在其中,然后再starter包的META-INF/spring.factories中写入配置类,那么springboot程序在启动的时候就会按照约定来加载该配置类
  • 开发人员只需要将相应的starter包依赖进应用中,进行相关的属性配置,就可以进行代码开发,而不需要单独进行bean对象的配置
posted @ 2022-06-21 22:03  Beginnerliu  阅读(463)  评论(1)    收藏  举报