1. Spring 有哪些特点?
轻量级:不管是 spring 的代码量还是运行所需要的开销,都算是轻量级的; 控制反转:控制反转就是创建对象的权利转交给 spring,程序要用的时候注入就行,降低了耦合度; 面向切面:将与业务无关却影响多个对象的代码抽取出来,形成切面。
2. Spring 的核心模块有哪些?
Spring 有七大核心模块:
Spring core:核心模块,提供 Spring 的基础功能; Spring Aop:提供了对面向切面编程的支持; Spring Context:应用上下文模块,向 Spring 框架提供上下文信息; Spring Dao:提供了数据库操作的基础结构; Spring ORM:提供了对持久层框架的支持; Spring Web:提供了对 web 开发的支持,基于 web 程序提供上下文; Spring Web MVC:构建 web 应用程序的 MVC 实现。
3. 什么是 Spring ioc?
IOC 就是控制反转,创建对象的权力交给 Spring,要用的时候直接从 IOC 容器中取出即可。它最核心的就是refresh方法,其包含了13个核心方法,大体流程是:首先会判断当前有没有 beanFactory 容器,如果没有,就创建 beanFactory 容器,然后通过 BeanDefinitionReader 对象读取配置文件或者注解,将配置都封装成 BeanDifinition 对象,再通过 BeanFactoryPostProcessor 来完成对 beanFactory 信息的修改或者扩展。然后会准备好 beanPostProcessor,监听器,广播器等,之后通过反射执行实例化操作,接着是进行 bean 的初始化,包括用 populateBean 方法填充属性,执行 aware 接口的方法,给 bean 设置所需要的容器内置的bean;接着执行 beanPostProcessor 来完成对 bean 的修改或者扩展,最后生成一个完整对象。AOP 功能就是通过 BeanPostProcessor 来实现的。
4. 说一说循环依赖怎么解决。
-循环依赖就是 A 对象有属性 b,B 对象有属性 A,这就是循环依赖。假如通过构造方法创建对象,创建 A 的时候要传入 B,B 又还没有,就得创建,创建 B 又得传入 A,这样就会无限套娃,所以 Spring 只能解决 setter 注入的循环依赖问题。它是用三级缓存解决的,其实也就是三个 map,一级缓存保存的是成品对象;二级缓存保存的是半成品对象,即实例化了但是属性还没赋值的对象;三级缓存保存的是 lambda 表达式。解决三级缓存的流程为:创建 A 对象之前,就会判断缓存中有没有 A,如果没有,就会创建 A 对象,在给 A 对象属性赋值之前,就会调用 addSingletonFactory 方法,该方法传入一个 lambda 表达式,与此同时会把这个 lambda 表达式放进三级缓存中;接着填充属性,发现属性 b 为空,就会实例化 B,实例化 B 和实例化 A 流程一样,在给 b 填充属性的时候,发现 a 为空,但是三级缓存中有 a 对象的 lambda 表达式,然后就会执行这段表达式,就得到了 a 对象,半成品 a 对象就会放到二级缓存中。赋值完的 b 对象,就是一个成品对象了,就会放到一级缓存中,回去再给 a 对象的 b 属性赋值时,就直接从一级缓存中取出 b 对象,赋值完的 a 对象也是一个成品对象了,也会放到一级缓存中。如果没有用到 aop,则用两级缓存,也可以解决循环依赖问题,如果用到了 aop,必须要三级,因为两级缓存无法区分对象的版本。
5. Spring bean 是安全的吗?如果不安全,要怎么解决?
spring bean 的作用域有五种,分别是 sigleton,prototype,request,session,global session,默认为 sigleton。作用域为 sigleton 的时候,它是不安全的,但是交给 spring 管理的 bean 一般都是无状态的,从这个角度来说也是安全的。如果要变成线程安全的,可以将作用域改为 prototype,表示每次获取 bean 都会创建一个新的 bean,也可以用 ThreadLocal 来保证线程安全。
6. 说一说 Spring bean 的生命周期。
实例化,设置属性,一些列可选的操作,比如执行自定义初始化方法,使用 bean,最后是销毁。
7. 依赖注入有哪些方式?
构造注入、set方法注入、静态工厂注入、工厂注入。
8. 自动装配有哪些方式?@Autowired 和 @Resource 有什么区别?
默认不自动装配,byName 是根据 bean 的名称装配,byType 是根据 bean 的类型装配,constructor 是构造注入,autodetect 是先根据构造注入,失败就根据类型注入。@Autowired 优先根据类型装配,没找到或找到多个再根据名称装配,@Resource 优先根据名称装配,没找到再根据类型装配。
9. 说说你对 Spring AOP 的理解。
AOP 就是面向切面编程,把与业务逻辑无关且同时影响多个对象的代码抽取出来形成切面,降低模块之间的耦合度,提高了代码的复用性。AOP 中的核心概念有:
连接点:要做增强的方法; 切点:连接点的集合; 通知:要对方法做的增强,分为前置通知,后置通知,环绕通知,异常通知和返回通知; 切面:切点加通知就是切面; 目标对象:被切面操作的对象; 织入:将切面应用到目标对象并且创建代理对象的过程。
10. Spring AOP 的原理是什么?
AOP 的原理是动态代理,如果代理的对象实现了接口,用的是 JDK 动态代理,如果没有实现接口,用的是 cglib 代理,cglib 封装了 asm,通过修改字节码文件实现代理。
11. 说一说 Spring 的事务。
Spring 事务是通过对数据库事务的支持来实现的,分为编程式事务和声明式事务,我们常用的是声明式事务,用注解的方式,对代码没有侵入。Spring 事务的传播行为有七种:
propagation_required:当前存在事务就加入,不存在就创建新事务; propagation_supported:当前存在事务就加入,不存在就以非事务方式运行; propagation_mandatory:当前存在事务就加入,不存在就报异常; propagation_required_new:创建新事物; propagation_not_support:当前存在事务就将事务挂起,然后以非事务方式运行; propagation_never:当前存在事务就报异常,必须以非事务方式运行; propagation_nested:当前存在事务就创建新事务作为嵌套事务,不存在就创建新事务。
12. 了解 SpringMVC 的工作流程吗?
请求先到前端控制器 DispatcherServlet; DispatcherServlet 请求处理器映射器 HandlerMapping; HandlerMapping 根据请求找到 Handler; 通过 HandlerAdapter 执行 Handler; 执行完返回 ModelAndView 给 DispatcherServlet; DispatcherServlet 请求视图解析器 ViewResolver; ViewResolver 解析视图,把 Model 数据渲染到视图,把 View 返回给用户。
13. BeanFactory 和 FactoryBean 有什么区别?
BeanFactory 是 Spring IOC 最底层的基础组件,管理 bean 的,而 FactoryBean 是用来创建 bean 的,是创建 bean 的一种方式,实现 Factory Bean 重写其方法可以创建 bean。
联系客服