JAVA常见面试题总结(九)Spring 和 SpringMVC
2021/7/29 9:35:48
本文主要是介绍JAVA常见面试题总结(九)Spring 和 SpringMVC,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
文章目录
- 1、Spring 是什么?为什么使用 Spring ?
- 2、Spring bean 的生命周期。
- 3、什么是 AOP ?
- 4、什么是 IoC ?
- 5、什么是循环依赖?
- 6、怎么解决循环依赖?
- 7、Spring 种为什么要使用三级缓存来解决循环依赖问题?二级缓存能解决循环依赖的问题吗?
- 8、BeanFactory 和 FactoryBean 有什么区别?
1、Spring 是什么?为什么使用 Spring ?
Spring 是什么?
Spring 是一个轻量级的简化企业应用开发的控制反转(IoC)和面向切面(AOP)的容器框架。
为什么使用 Spring ?
-
轻量
从大小和开销两方面而言 Spring 都是轻量的。完整的 Spring 框架可以在一个大小只有1MB多的JAR文件里发布。并且 Spring 所需的处理开销也是微不足道的。Spring 还是非侵入式的:Spring 应用中的对象不依赖于 Spring 的特定类。
-
控制反转
Spring 通过控制反转(IoC)技术促进了松耦合。当应用了 IoC ,一个对象依赖的其它对象就会通过被动的方式传递进来(DI),而不是这个对象自己创建或者查找依赖对象。
-
面向切面
Spring 提供了面向切面编程的丰富支持,允许通过分离应用的业务逻辑与系统级服务(例如审计(auditing)和事务(transaction)管理)进行内聚性开发。应用对象只需要完成业务逻辑,而不需要关心其它的内容,例如日志或事务。
-
容器
Spring包含并管理应用对象的配置和生命周期,在这个意义上它是一种容器,你可以配置你的每个bean如何被创建——基于一个可配置原型(prototype),你的bean可以创建一个单独的实例或者每次需要时都生成一个新的实例——以及它们是如何相互关联的。然而,Spring不应该被混同于传统的重量级的EJB容器,它们经常是庞大与笨重的,难以使用。
-
框架
Spring可以将简单的组件配置、组合成为复杂的应用。在Spring中,应用对象被声明式地组合,典型地是在一个XML文件里。Spring也提供了很多基础功能(事务管理、持久化框架集成等等),将应用逻辑的开发留给了你。
Spring 的这些特性使开发人员能够编写更加干净、更可管理、并且更易于测试的代码。它们也为 Spring 中的各种模块提供了基础支持。
2、Spring bean 的生命周期。
总体上说 Spring bean 的生命周期只有四个:
- 实例化 Instantiation
- 属性赋值 Populate
- 初始化 Initialization
- 销毁 Destruction
3、什么是 AOP ?
AOP (Aspect Oriented Programming)面向方面编程,也有叫面向切面编程。AOP 可以说是 OOP (Object Oriented Programming)的补充和完善。OOP 引入封装、继承和多态等概念来建立一种对象层次结构,用以模拟公共行为的一个集合。当我们要为分散的对象引入公共行为的时候,OOP 则显的无能为力。也就是说,OOP 允许你定义从上到下的关系,但并不适合定义从左到右的关系。例如日志功能,日志功能往往水平的散布在所有的对象层次中,而与它所散布到的对象的核心功能毫无关系。这种散布在各处的无关代码被称为横切代码,在 OOP 设计中,它导致了大量代码的重复,不利于各个模块的重用。
而 AOP 技术则恰恰相反,它利用一种称为“横切”的技术,解剖开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其命名为“Aspect”,即方面。方面就是把与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,减少系统的代码重复,降低模块间的耦合度,并有利于未来的可操作性和可维护性。
使用“横切”技术,AOP把软件系统分为两个部分:核心关注点和横切关注点。业务处理的主要流程是核心关注点,与之关系不大的部分是横切关注点。横切关注点的一个特点是,他们经常发生在核心关注点的多处,而各处都基本相似。比如权限认证、日志、事务处理。Aop 的作用在于分离系统中的各种关注点,将核心关注点和横切关注点分离开来。正如Avanade公司的高级方案构架师Adam Magee所说,AOP的核心思想就是“将应用程序中的商业逻辑同对其提供支持的通用服务进行分离。”
4、什么是 IoC ?
IoC(Inversion of Control),中文一般称之为“控制反转”。
要了解什么是 IoC ,就要先了解 IoC 是为了解决什么问题而出现的。软件工程的目标之一就是降低系统或模块之间的耦合度。IoC 就是软件专家 Michael Mattson 提出的降低对象间耦合度的理论。
IoC 提出的观点大体是这样的:借助于“第三方”实现具有依赖关系的对象之间的解耦,如下图:
大家看到了吧,由于引入了中间位置的“第三方”,也就是 IoC 容器,使得A、B、C、D这四个对象没有了耦合关系,控制权全部交给了“第三方” IoC 容器。所以,IoC 容器成了整个系统的关键核心,它起到了一种类似“粘合剂”的作用,把系统中的所有对象粘合在一起发挥作用,如果没有这个“粘合剂”,对象与对象之间会彼此失去联系,这就是有人把 IoC 容器比喻成“粘合剂”的由来。
我们再来做个试验:把上图中间的IOC容器拿掉,然后再来看看这套系统:
大家可以看到,拿掉 IoC 容器之后的系统就是我们要实现系统功能所需完成的全部内容,此时A、B、C、D这四个对象已经没有了耦合关系,这样的话我们要实现A的时候就无需关心B、C和D了,对象间的关系已经降低到了最低程度。
最后我们再来总结一下:软件系统在没有引入 IoC 容器之前,如图1所示,对象A依赖于对象B,那么在初始化或运行到某一点的时候就必须自己主动去创建对象B,或者使用已经创建的对象B。无论是创建还是使用对象B,控制权都在自己手上。而软件系统在引入 IoC 容器之后,这种情形就完全改变了,如图2所示,由于 IoC 容器的加入,对象A和B之间失去了直接联系,所以当对象A运行到需要对象B的时候,IoC 容器就会主动创建一个对象B注入到对象A所需要的地方。由前后的对比,可以看出:对象A获得依赖对象B的过程,由主动行为变成了被动行为,控制权颠倒过来了,这就是“控制反转”这个名称的由来。
5、什么是循环依赖?
循环依赖就是Bean之间互相依赖形成一个环,例如:BeanA 依赖 BeanB ,BeanB 又依赖 BeanA 。
代码示例:
class A{ B b; } class B{ A a; }
6、怎么解决循环依赖?
循环依赖有多种方式,其中通过构造器注入的循环依赖是无法解决的,通过setter方法注入的循环依赖是可以解决的。
构造方法注入的循环依赖:
class A{ B b; public A(B b){ this.b = b; } } class B{ A a; public B(A a){ this.a = a; } }
setter方法注入的循环依赖:
class A{ B b; public void setB(B b){ this.b = b; } } class B{ A a; public void setA(A a){ this.a = a; } }
Spring 解决循环依赖的理论依据基于 Java 的引用传递,当获取对象的引用时,对象的值是可以延后设置的。(构造器注入方式的除外,因为构造器的调用早于引用的获取)
7、Spring 种为什么要使用三级缓存来解决循环依赖问题?二级缓存能解决循环依赖的问题吗?
三级缓存是 DefaultSingletonBeanRegistry 中的三个Map对象,通常情况下我们称singletonObjects为一级缓存,earlySingletonObjects为二级缓存,singletonFactories为三级缓存。
“等级” | 名称 | 说明(作用) |
---|---|---|
一级 | singletonObjects | 存放初始化完成的单例对象 |
二级 | earlySingletonObjects | 存放已经实例化但还未初始化完成的单例对象(未完成属性注入) |
三级 | singletonFactories | 存放单例工厂的缓存,用来解决aop的问题 |
如果只是单纯的解决循环依赖问题,二级缓存就已经可以做到了(不考虑性能问题,设计精妙的一级缓存也能解决),之所以要加三级缓存是因为我们在Spring中使用的Bean对象一般都是代理对象,不是直接创建的实例对象,三级缓存就是解决循环依赖中aop问题的。
8、BeanFactory 和 FactoryBean 有什么区别?
BeanFactory是个Factory,也就是IOC容器或对象工厂,FactoryBean是个Bean。在Spring中,所有的Bean都是由BeanFactory(也就是IOC容器)来进行管理的。但对FactoryBean而言,这个Bean不是简单的Bean,而是一个能生产或者修饰对象生成的工厂Bean,它的实现与设计模式中的工厂模式和修饰器模式类似。
这篇关于JAVA常见面试题总结(九)Spring 和 SpringMVC的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-20RabbitMQ教程:新手入门指南
- 2024-11-20Redis教程:新手入门指南
- 2024-11-20SaToken教程:新手入门指南
- 2024-11-20SpringBoot教程:从入门到实践
- 2024-11-20Java全栈教程:从入门到实战
- 2024-11-20Java微服务系统教程:入门与实践指南
- 2024-11-20Less教程:初学者快速上手指南
- 2024-11-20MyBatis教程:新手快速入门指南
- 2024-11-20QLExpress教程:初学者快速入门指南
- 2024-11-20订单系统教程:从入门到实践的全面指南