通过面试题学Spring

准备面试复习Spring的时候详细的看了一下Spring理论知识,结合网上的面试题,写了这篇博客。如果需要更详细的内容,推荐我的另一篇文章详解Spring

为什么使用Spring(优缺点)?

  1. spring属于低侵入式设计,代码的污染极低;
  2. IoC容器往往是轻量级的,特别是与EJB容器相比。这是有利于在有限的内存和CPU资源的计算机上开发和部署应用程序。
  3. spring的**DI(依赖注入)**机制将对象之间的依赖关系交由框架处理,减低组件的耦合性;
  4. Spring提供了AOP技术,支持将一些通用任务,如安全、事务、日志、权限等进行集中式管理,从而提供更好的复用。
  5. 在Spring测试应用程序很简单,因为依赖环境的代码被移入到框架本身。此外,通过使用JavaBean-style pojo方式,使用依赖注入注入测试数据变得更容易。
  6. Spring提供了一致的事务管理界面,可以管理小到一个本地事务(例如,使用一个数据库)和大到全局事务(例如,使用JTA)
  7. spring对于主流的应用框架提供了集成支持(Spring不排斥各种优秀的开源框架如Struts,Hibernate)
  8. Spring的web框架是一个设计良好的web MVC框架,它可以很好的替代其它web框架如struts或者其它web框架。

Spring的IoC理解:

  • DI依赖注入,和控制反转(IoC)是同一个概念的不同角度的描述,即 应用程序在运行时依赖IoC容器来动态注入对象需要的外部资源。
  • IoC(Inverse of Control:控制反转)是一种设计思想,就是将原本在程序中手动创建对象的控制权,交由Spring容器来管理。容器根据配置文件去创建实例和管理各个实例之间的依赖关系,对象与对象之间松散耦合,利于功能的复用。
  • Spring的DI有三种注入方式 :构造器注入、setter方法注入、根据注解注入。

之前某个类引用另一个类时,需要在类中new一个对象,现在通过IOC将这一过程交给Spring容器来执行。Spring使用java的反射机制和配置文件去创建实例和管理各个实例之间的依赖关系,运行时通过DI动态注入对象需要的外部资源。

IoC让相互协作的组件保持松散的耦合

什么是控制反转(Inversion of Control)与依赖注入(Dependency Injection)?

  1. 控制反转:是指将创建对象的功能交给Spring容器,在我们需要使用对象的时候不需要自己创建,可以直接从容器中获取。
  2. 依赖注入:动态的向某个对象提供它所依赖的其他对象

BeanFactory和ApplicationContext有什么区别?

  • 表面上看,applicationContext和BeanFactory是一样。同样加载bean定义,将bean连接在一起,分发bean。
  • 但applicationContext还增加了企业所需要的功能,比如,从属性文件中解析文本信息和将事件传递给所指定的监听器。ApplicationContext 包含BeanFactory 所有的功能,一般情况下,相对于BeanFactory,ApplicationContext会更加优秀。
  • 在资源宝贵的移动设备或者基于 applet 的应用当中, BeanFactory 会被优先选择。

三个常用的ApplicationContext实现是:
在这里插入图片描述

AOP理解

概念
将那些与业务无关,却为业务模块所共同调用的逻辑或责任(例如事务处理、日志管理、权限控制等)封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可拓展性和可维护性。
AOP的实现

Spring AOP 和 AspectJ AOP 有什么区别?

  • Spring AOP 属于运行时增强,而 AspectJ 是编译时增强。 Spring AOP 基于代理(Proxying),而 AspectJ 基于字节码操作(Bytecode Manipulation)。

  • Spring AOP 已经集成了 AspectJ ,AspectJ 应该算的上是 Java 生态系统中最完整的 AOP 框架了。AspectJ 相比于 Spring AOP 功能更加强大,但是 Spring AOP 相对来说更简单,

  • 如果我们的切面比较少,那么两者性能差异不大。但是,当切面太多的话,最好选择 AspectJ ,它比Spring AOP 快很多。

Bean的理解

定义
bean 是一个被实例化,组装,并通过 Spring IoC 容器所管理的对象。这些 bean 是由用容器提供的配置元数据创建的。

Spring支持的几种bean的作用域?

Spring容器中的bean可以分为5个范围:

  • global-session: 全局session作用域,仅仅在基于portlet的web应用中才有意义,Spring5已经没有了。Portlet是能够生成语义代码(例如:HTML)片段的小型Java Web插件。它们基于portlet容器,可以像servlet一样处理HTTP请求。但是,与 servlet 不同,每个 portlet 都有不同的会话

Spring Bean的生命周期?

1.Spring 容器根据配置中的 bean 定义中实例化 bean。
2. Spring 使用依赖注入填充所有属性,如 bean 中所定义的配置。
3. 如果 bean 实现 BeanNameAware 接口,则工厂通过传递 bean 的 ID 来调用 setBeanName()。
4. 如果 bean 实现 BeanFactoryAware 接口,工厂通过传递自身的实例来调用 setBeanFactory()。
5. 如果存在与 bean 关联的任何 BeanPostProcessors,则调用 postProcessBeforeInitialization() 方法。
6. 如果为 bean 指定了 init 方法( 的 init-method 属性),那么将调用它。
7. 最后,如果存在与 bean 关联的任何 BeanPostProcessors,则将调用 postProcessAfterInitialization() 方法。
8. 如果 bean 实现 DisposableBean 接口,当 spring 容器关闭时,会调用 destory()。
9. 如果为 bean 指定了 destroy 方法( 的 destroy-method 属性),那么将调用它。

在这里插入图片描述

Spring框架中的单例Beans是线程安全的么?

Spring框架并没有对单例bean进行任何多线程的封装处理。关于单例bean的线程安全和并发问题需要开发者自行去搞定。但实际上,大部分的Spring bean并没有可变的状态(比如Serview类和DAO类),所以在某种程度上说Spring的单例bean是线程安全的。如果你的bean有多种状态的话(比如 View Model 对象),就需要自行保证线程安全。最浅显的解决办法就是将多态bean的作用域由“singleton”变更为“prototype”。

Spring如何处理线程并发问题?

在一般情况下,只有无状态的Bean才可以在多线程环境下共享,在Spring中,绝大部分Bean都可以声明为singleton作用域,因为Spring对一些Bean中非线程安全状态采用ThreadLocal进行处理,解决线程安全问题。

ThreadLocal和线程同步机制都是为了解决多线程中相同变量的访问冲突问题。同步机制采用了“时间换空间”的方式,仅提供一份变量,不同的线程在访问前需要获取锁,没获得锁的线程则需要排队。而ThreadLocal采用了“空间换时间”的方式。

ThreadLocal会为每一个线程提供一个独立的变量副本,从而隔离了多个线程对数据的访问冲突。因为每一个线程都拥有自己的变量副本,从而也就没有必要对该变量进行同步了。ThreadLocal提供了线程安全的共享对象,在编写多线程代码时,可以把不安全的变量封装进ThreadLocal

Spring MVC

流程?

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

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

  1. 工厂模式:BeanFactory就是简单工厂模式的体现,用来创建对象的实例;
  2. 单例模式:Bean默认为单例模式。
  3. 代理模式:Spring的AOP功能用到了JDK的动态代理和CGLIB字节码生成技术;
  4. 模板方法:用来解决代码重复的问题。比如. RestTemplate, JmsTemplate, JpaTemplate。
  5. 观察者模式:Spring 事件驱动模型就是观察者模式很经典的一个应用。定义对象键一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知被制动更新,如Spring中listener的实现–ApplicationListener。
  6. 适配器模式 :Spring AOP 的增强或通知(Advice)使用到了适配器模式、spring MVC 中也是用到了适配器模式适配Controller。

Spring 事务

实现方式与原理?

Spring事务的本质其实就是数据库对事务的支持,没有数据库的事务支持,spring是无法提供事务功能的。真正的数据库层的事务提交和回滚是通过binlog或者redo log实现的。

Spring 管理事务的方式有几种?

  1. 编程式事务,在代码中硬编码TransactionTemplate。(不推荐使用)

  2. 声明式事务,在配置文件中配置(推荐使用)

    声明式事务管理建立在AOP之上的。其本质是通过AOP功能,对方法前后进行拦截,将事务处理的功能编织到拦截的方法中,也就是在目标方法开始之前加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务

    • 基于XML的声明式事务
    • 基于注解的声明式事务
      声明式事务最大的优点就是不需要在业务逻辑代码中掺杂事务管理的代码,只需在配置文件中做相关的事务规则声明或通过@Transactional注解的方式,便可以将事务规则应用到业务逻辑中。

声明式事务管理要优于编程式事务管理,这正是spring倡导的非侵入式的开发方式,使业务代码不受污染,只要加上注解就可以获得完全的事务支持。唯一不足地方是,最细粒度只能作用到方法级别,无法做到像编程式事务那样可以作用到代码块级别。

Spring 事务中的隔离级别有哪几种?

在这里插入图片描述

spring的事务传播行为?

spring事务的传播行为说的是,当多个事务同时存在的时候,spring如何处理这些事务的行为。
在这里插入图片描述

发布了14 篇原创文章 · 获赞 3 · 访问量 606

猜你喜欢

转载自blog.csdn.net/qq_41011723/article/details/104886493