# 什么是 Spring?
Spring 是一个开源的 Java EE 开发框架。Spring 框架的核心功能可以应用在任何 Java 应用程序中,但对 Java EE 平台的 Web 应用程序有更好的扩展性。Spring 框架的目标是使得 Java EE 应用程序的开发更加简介,通过使用 POJO 为基础的编程模型促进良好的编程风格。
# Spring 的核心
IOC (控制反转) 或 DI (依赖注入):解决对象之间的依赖关系,把所有 bean 的依赖关系通过配置文件或注解关联起来,降低耦合度
AOP (面向切面编程):解决业务逻辑的耦合,用于那些将与业务无关,但却对多个对象产生公共行为和逻辑,抽象并封装成一个可重用的模块,减少系统中的重复代码降低模块间耦合度
AOP 最直接的体现就是事务管理、权限判断、日志等。
# Spring 的优点
- 降低组件之间的耦合度
- 提供了众多服务,如事务管理、消息服务等
- 提供了 AOP 技术,容易实现权限管理、运行期监控等
- 能够与各种优秀的框架继承
- 属于低侵入式设计,代码的污染性极低
- 提供了 DI 机制,降低了业务对象替换的复杂性
# spring 有哪些主要模块?
- spring core:框架的最基础部分,提供 ioc 和依赖注⼊特性。
- spring context:构建于 core 封装包基础上的 context 封装包,提供了⼀种框架式的对象访问⽅ 法。
- spring dao:Data Access Object 提供了 JDBC 的抽象层。
- spring aop:提供了⾯向切⾯的编程实现,让你可以⾃定义拦截器、切点等。
- spring web:提供了针对 web 开发的集成特性,例如⽂件上传,利⽤ servlet listeners 进⾏ ioc 容器初始化和针对 web 的 ApplicationContext。
- spring web mvc:spring 中的 mvc 封装包提供了 web 应⽤的 Model-View-Controller(MVC)的 实现
# spring 常⽤的注入方式有哪些?
- setter 属性注入
- 构造方法注入
- 注解方式注入
# Spring 事务实现方式
编程式事物管理:可以通过编程的方式管理事物。这种方式带来了很大的灵活性,但很难维护。
声明式事物管理:可以将事物管理和业务代码分离,只需要通过注解或者 XML 配置管理事物。
# Spring 框架的事务管理有哪些优点
- 为不同的事物 API 提供了统一的编程模型。
- 为编程式事物管理提供了一个简单的 API 而非一系列复杂的事物 API。
- 支持声明式事物管理。
- 可以和 Spring 的多种数据访问技术很好的融合。
# Spring 事务的传播特性
PROPAGATION_REQUIRE:需要,如果存在一个事务就支持该事务,没有就开启事务
PROPAGATION_SUPPORTS:支持,如果存在一个事务就支持该事务,没有就以非事务执行
PROPAGATION_MANADTORY:必须,如果存在一个事务就支持该事务,没有就抛出异常
PROPAGATION_REQUIRED_NEW:总是开启一个新事务,如果一个事务存在就将该事务挂起
PROPAGATION_NOT_SUPPORTS:不支持,总是以非事务执行,并挂起任何以存在的事务
PROPAGATION_NEVER:绝不,总是以非事务执行,如果存在一个事务,就抛出异常
PROPAGATION_NESTED:嵌套的,如果有事务就嵌套,没有就开启事务
# Spring 的事务隔离
有五大隔离级别,默认 (ISOLATION_DEFAULT) 是使用数据库的隔离级别,其他四个隔离级别跟数据库一致
- ISOLATION_DEFAULT:默认隔离级别,数据库用什么,我就用什么
- ISOLATION_READ_UNCOMMITTED:读未提交,最低的隔离级别,事物未提交前,就可能被其他事物读取(会出现幻读、脏读、不可重复读)
- ISOLATION_READ_COMMITTED:读已提交,一个事物提交后才能被其他事物读取到(会造成幻读、不可重复读),sql server 的默认级别
- ISOLATION_REPAREBLE_READ:可重复读,保证多次读取同一个数据时,其值和事物开始时的内容是一致的,禁止读取到别的事物未提交的数据(会造成幻读),mysql 的默认级别
- ISOLATION_SERIALIZABLE:序列化,代价最高最可靠的隔离级别,该级别能防止脏读、不可重复读、幻读
# Spring 中支持的 bean 作用域
spring 框架支持如下五种不同的作用域:
singleton:在 Spring IOC 容器中仅存在一个 Bean 实例,Bean 以单实例的方式存在。
prototype:一个 Bean 可以定义多个实例。
request:每次 HTTP 请求都会创建一个新的 Bean,该作用域仅适用于 WebApplicationContext 环境。
session:一个 HTTP Session 定义一个 Bean。该作用域是适用于 WebApplicationContext 环境。
globalSession:同一个全局 HTTP Session 定义一个 Bean。该作用域仅适用于 WebApplicationContext 环境。
bean 默认的 scope 属性是 singleton。
# 解释 Spring 框架中 bean 的生命周期
- 首先容器加载启动后,会对 scope 为 singleton 且非懒加载的 bean 进行实例化。
- 按照 Bean 定义配置信息,注入所有属性。
- 如果 Bean 实现了 BeanNameAware 接口,会回调该接口的 setBeanName () 方法,传入 Bean 的 id,此时 Bean 就获得了自己在配置文件中的 id。
- 如果 Bean 实现了 BeanFactoryAware 接口,会回调接口的 setBeanFactory () 方法,传入该 Bean 的 BeanFactory,这样 Bean 就获得了自己所在的 BeanFactory。
- 如果 Bean 实现了 ApplicationContextAware 接口,会回调接口的 setApplicationContext () 方法,传入该 Bean 的 ApplicationContext,此时 Bean 就获得了自己所在的 ApplicarionContext。
- 如果 Bean 实现了 BeanPostProcessor 接口,则会回调接口的 postProcessBeforeInitialization () 方法。
- 如果 Bean 实现了 InitializingBean 接口,则会回调接口的 afterPropertiesSet () 方法。
- 如果 Bean 配置了 init-method 方法,则会执行 init-method 配置的方法。
- 如果 Bean 实现了 BeanPostProcessor 接口,则会回调接口的 postProcessAfterInitialization () 方法。
- 经过流程 9 之后,就可以使用该 Bean 了,对于 scope 为 singleton 的 Bean,Spring 的 IOC 容器会缓存一份该 Bean 的实例,而对于 scope 为 prototype 的 Bean,每次被调用都会 new 一个新的对象,其生命周期就交给调用方管理了,不再是 Spring 容器进行管理了。
- 容器关闭后,如果 Bean 实现了 DispoableBean 接口,则会回调该接口的 destroy () 方法。
- 如果配置了 destroy-method 方法,则会执行 destory-method 配置的方法,到此,整个 Bean 的生命周期结束。
# Spring 有几种配置方式
- 基于 XML 文件的配置
这种配置文件的格式常用 <beans> 开头,然后运用一系列的 bean 定义和专门的应用配置选项组成。Spring XML 配置方法是使用 Spring 命名空间所支持的一些列 XML 标签来实现的。
- 基于注解配置
可以使用注解的方式来代替 XML 方式的 bean 元素的配置,常见的依赖注入的一些注解有:@controller,@Service@Autowried@RequestMapping@RequestParam
- 组件扫描
容器会扫描 base-package 指定的包及其子包下面的所有类,如果该类有一些特定的注解,则会纳入容器管理。
- 基于 Java 配置
# 什么叫延迟加载
默认情况下,容器启动之后会将所有作用域为单例的 bean 创建好;但是有的业务场景不需要它提前创建好。
此时,可以在 bean 中设置 lzay-init="true",这样,当容器启动之后,作用域为单例的 bean 不在创建。
# Spring 中的 bean 是线程安全的吗?
Spring 框架并没有对单例的 bean 进行多线程的封装处理,线程安全问题和并发问题,需要开发者自己考虑。
但实际上,大部分的 Spring bean 并没有可变的状态(如:service 类,dao 类),所以在某种程度上来说 Spring 单例 bean 是线程安全的,如果 bean 有多种状态(如:View Model 对象),就需要自行考虑线程安全问题。
# Spring 有哪些设计模式?
- 简单工厂模式:Spring 中 BeanFactory 就是简单工厂模式的体现。
- 工厂方法模式:应用程序有自己的工厂对象来创建 bean,如果将应用程序自己的工厂对象交给 Spring 管理,那么 Spring 管理的就不是普通的 bean,而不是工厂 bean
- 单例模式:Spring 下默认的 bean 均为 singleton
- 适配器模式:SpringAOP 的增强或通知(Advice)使用了适配器模式
- 包装器模式:项目中需要连接多个数据库,而且不同的客户端在每次访问中根据需要会访问不同的数据库,这种模式让我们可以根据客户端的需求能够动态切换不同的数据源
- 代理模式:AOP 功能的是实现,有 JDK 代理和 Cglib 代理
- 策略模式:
- 模板方法模式:Spring 中 jdbcTemplate、hibrenateTemplate 等以 template 结尾的对数据库操作的类,都使用了模板模式
- 观察者模式:Spring 的事件驱动模型使用的使观察者模式