1、什么是 Spring?
Spring 是一个开源的 Java EE 开发框架。Spring 框架的外围性能能够利用在任何 Java 应用程序中,但对 Java EE 平台上的 Web 应用程序有更好的扩展性。Spring 框架的指标是使得 Java EE 应用程序的开发更加简捷,通过应用 POJO 为根底的编程模型促成良好的编程格调。
2、Spring 有哪些长处?
轻量级:Spring 在大小和透明性方面相对属于轻量级的,根底版本的 Spring 框架大概只有 2MB。
管制反转(IOC):Spring 应用管制反转技术实现了松耦合。依赖被注入到对象,而不是创立或寻找依赖对象。
面向切面编程(AOP):Spring 反对面向切面编程,同时把利用的业务逻辑与零碎的服务拆散开来。
容器:Spring 蕴含并管理应用程序对象的配置及生命周期。
MVC 框架:Spring 的 web 框架是一个设计低劣的 web MVC 框架,很好的取代了一些 web 框架。
事务管理 :Spring 对下至本地业务上至全局业务(JAT) 提供了对立的事务管理接口。
异样解决 :Spring 提供一个不便的 API 将特定技术的异样(由 JDBC, Hibernate, 或 JDO 抛出) 转化为统一的、Unchecked 异样。
3、Spring 事务实现形式
编程式事务管理:这意味着你能够通过编程的形式治理事务,这种形式带来了很大的灵活性,但很难保护。
申明式事务管理:这种形式意味着你能够将事务管理和业务代码拆散。你只须要通过注解或者 XML 配置管理事务。
4、Spring 框架的事务管理有哪些长处
它为不同的事务 API(如 JTA, JDBC, Hibernate, JPA, 和 JDO)提供了对立的编程模型。它为编程式事务管理提供了一个简略的 API 而非一系列简单的事务 API(如 JTA). 它反对申明式事务管理。它能够和 Spring 的多种数据拜访技术很好的交融。
5、spring 事务定义的流传规定
流传机制 | 阐明 |
---|---|
PROPAGATION_REQUIRED | 如果以后没有事务,就创立一个事务,如果曾经存在事务,就退出到这个事务。以后流传机制也是 spring 默认流传机制 |
PROPAGATION_REQUIRES_NEW | 新建事务,如果以后存在事务,就抛出异样 |
PROPAGATION_SUPPORTS | 反对以后事务,如果以后没有事务,就以非事务形式执行 |
PROPAGATION_NOT_SUPPORTED | 以非事务形式执行操作,如果以后存在事务,就把以后事务挂起 |
PROPAGATION_MANDATORY | 应用以后的事务,如果以后没有事务,就抛出异样 |
PROPAGATION_NEVER | 以非事务形式执行,如果以后存在事务,则抛出异样 |
PROPAGATION_NESTED | 如果以后存在事务,则在嵌套的事务内执行。如果以后没有事务,则执行与 PROPAGATION_REQUIRED 相似的操作 |
6、Spring 事务底层原理
划分处理单元——IoC
因为 spring 解决的问题是对单个数据库进行部分事务处理的,具体的实现首先用 spring 中的 IoC 划分了事务处理单元。并且将对事务的各种配置放到了 ioc 容器中(设置事务管理器,设置事务的流传个性及隔离机制)。
AOP 拦挡须要进行事务处理的类
Spring 事务处理模块是通过 AOP 性能来实现申明式事务处理的,具体操作(比方事务履行的配置和读取,事务对象的形象),用 TransactionProxyFactoryBean 接口来应用 AOP 性能,生成 proxy 代理对象,通过 TransactionInterceptor 实现对代理办法的拦挡,将事务处理的性能编织到拦挡的办法中。读取 ioc 容器事务配置属性,转化为 spring 事务处理须要的外部数据结构(TransactionAttributeSourceAdvisor),转化为 TransactionAttribute 示意的数据对象。
对事务处理实现(事务的生成、提交、回滚、挂起)
spring 委托给具体的事务处理器 实现。实现了一个形象和适配。适配的具体事务处理器:DataSource 数据源反对、hibernate 数据源事务处理反对、JDO 数据源事务处理反对,JPA、JTA 数据源事务处理反对。这些反对都是通过设计 PlatformTransactionManager、AbstractPlatforTransaction 一系列事务处理的反对。为罕用数据源反对提供了一系列的 TransactionManager。
联合
PlatformTransactionManager 实现了 TransactionInterception 接口,让其与 TransactionProxyFactoryBean 联合起来,造成一个 Spring 申明式事务处理的设计体系。
7、Spring MVC 运行流程
第一步:发动申请到前端控制器(DispatcherServlet)
第二步:前端控制器申请 HandlerMapping 查找 Handler(能够依据 xml 配置、注解进行查找)
第三步:处理器映射器 HandlerMapping 向前端控制器返回 Handler
第四步:前端控制器调用处理器适配器去执行 Handler
第五步:处理器适配器去执行 Handler
第六步:Handler 执行实现给适配器返回 ModelAndView
第七步:处理器适配器向前端控制器返回 ModelAndView(ModelAndView 是 springmvc 框架的一个底层对象,包含 Model 和 view)
第八步:前端控制器申请视图解析器去进行视图解析(依据逻辑视图名解析成真正的视图(jsp))
第九步:视图解析器向前端控制器返回 View
第十步:前端控制器进行视图渲染(视图渲染将模型数据 (在 ModelAndView 对象中) 填充到 request 域)
第十一步:前端控制器向用户响应后果
8、BeanFactory 和 ApplicationContext 有什么区别?
ApplicationContext提供了一种解决文档信息的办法,一种加载文件资源的形式(如图片),他们能够向监听他们的 beans 发送音讯。
另外,容器或者容器中 beans 的操作,这些必须以 bean 工厂的编程形式解决的操作能够在利用上下文中以申明的形式解决。利用上下文实现了 MessageSource,该接口用于获取本地音讯,理论的实现是可选的。
相同点:两者都是通过 xml 配置文件加载 bean,ApplicationContext 和 BeanFacotry 相比, 提供了更多的扩大性能。
不同点:BeanFactory 是提早加载, 如果 Bean 的某一个属性没有注入,BeanFacotry 加载后,直至第一次应用调用 getBean 办法才会抛出异样;而 ApplicationContext 则在初始化本身是测验,这样有利于查看所依赖属性是否注入;所以通常状况下咱们抉择应用 ApplicationContext。
9、什么是 Spring Beans?
Spring Beans 是形成 Spring 利用外围的 Java 对象。这些对象由 Spring IOC 容器实例化、组装、治理。这些对象通过容器中配置的元数据创立,例如,应用 XML 文件中定义的创立。
在 Spring 中创立的 beans 都是单例的 beans。在 bean 标签中有一个属性为”singleton”, 如果设为 true,该 bean 是单例的,如果设为 false,该 bean 是原型 bean。Singleton 属性默认设置为 true。因而,spring 框架中所有的 bean 都默认为单例 bean。
10、说一下 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”。
11、Spring 的单例实现原理
Spring 框架对单例的反对是采纳单例注册表的形式进行实现的,而这个注册表的缓存是 HashMap 对象,如果配置文件中的配置信息不要求应用单例,Spring 会采纳新建实例的形式返回对象实例。
12、解释 Spring 框架中 bean 的生命周期
ApplicationContext 容器中,Bean 的生命周期流程如上图所示,流程大抵如下:
1. 首先容器启动后,会对 scope 为 singleton 且非懒加载的 bean 进行实例化,
2. 依照 Bean 定义信息配置信息,注入所有的属性,
3. 如果 Bean 实现了 BeanNameAware 接口,会回调该接口的 setBeanName()办法,传入该 Bean 的 id,此时该 Bean 就取得了本人在配置文件中的 id,
4. 如果 Bean 实现了 BeanFactoryAware 接口, 会回调该接口的 setBeanFactory()办法,传入该 Bean 的 BeanFactory,这样该 Bean 就取得了本人所在的 BeanFactory,
5. 如果 Bean 实现了 ApplicationContextAware 接口, 会回调该接口的 setApplicationContext()办法,传入该 Bean 的 ApplicationContext,这样该 Bean 就取得了本人所在的 ApplicationContext,
6. 如果有 Bean 实现了 BeanPostProcessor 接口,则会回调该接口的 postProcessBeforeInitialzation()办法,
7. 如果 Bean 实现了 InitializingBean 接口,则会回调该接口的 afterPropertiesSet()办法,
8. 如果 Bean 配置了 init-method 办法,则会执行 init-method 配置的办法,
9. 如果有 Bean 实现了 BeanPostProcessor 接口,则会回调该接口的 postProcessAfterInitialization()办法,
10. 通过流程 9 之后,就能够正式应用该 Bean 了, 对于 scope 为 singleton 的 Bean,Spring 的 ioc 容器中会缓存一份该 bean 的实例,而对于 scope 为 prototype 的 Bean, 每次被调用都会 new 一个新的对象,期生命周期就交给调用方治理了,不再是 Spring 容器进行治理了
11. 容器敞开后,如果 Bean 实现了 DisposableBean 接口,则会回调该接口的 destroy()办法,
12. 如果 Bean 配置了 destroy-method 办法,则会执行 destroy-method 配置的办法,至此,整个 Bean 的生命周期完结
13、Resource 是如何被查找、加载的
Resource 接口是 Spring 资源拜访策略的形象,它自身并不提供任何资源拜访实现,具体的资源拜访由该接口的实现类实现——每个实现类代表一种资源拜访策略。Spring 为 Resource 接口提供了如下实现类:
① UrlResource:拜访网络资源的实现类。
② ClassPathResource:拜访类加载门路里资源的实现类。
③ FileSystemResource:拜访文件系统里资源的实现类。
④ ServletContextResource:拜访绝对于 ServletContext 门路里的资源的实现类:
· InputStreamResource:拜访输出流资源的实现类。
· ByteArrayResource:拜访字节数组资源的实现类。
这些 Resource 实现类,针对不同的的底层资源,提供了相应的资源拜访逻辑,并提供便捷的包装,以利于客户端程序的资源拜访。
14、解释主动拆卸的各种模式?
主动拆卸提供五种不同的模式供 Spring 容器用来主动拆卸 beans 之间的依赖注入:
no:默认的形式是不进行主动拆卸,通过手工设置 ref 属性来进行拆卸 bean。
byName:通过参数名主动拆卸,Spring 容器查找 beans 的属性,这些 beans 在 XML 配置文件中被设置为 byName。之后容器试图匹配、拆卸和该 bean 的属性具备雷同名字的 bean。
byType:通过参数的数据类型主动主动拆卸,Spring 容器查找 beans 的属性,这些 beans 在 XML 配置文件中被设置为 byType。之后容器试图匹配和拆卸和该 bean 的属性类型一样的 bean。如果有多个 bean 符合条件,则抛出谬误。
constructor:这个同 byType 相似,不过是利用于构造函数的参数。如果在 BeanFactory 中不是恰好有一个 bean 与结构函数参数雷同类型,则抛出一个重大的谬误。
autodetect:如果有默认的构造方法,通过 construct 的形式主动拆卸,否则应用 byType 的形式主动拆卸。
15、Spring 中的依赖注入是什么?
依赖注入 作为管制反转 (IOC) 的一个层面,能够有多种解释形式。在这个概念中,你不必创建对象而只须要形容如何创立它们。你不用通过代码间接的将组件和服务连贯在一起,而是通过配置文件阐明哪些组件须要什么服务。之后 IOC 容器负责连接。
16、有哪些不同类型的 IOC(依赖注入)?
结构器依赖注入:结构器依赖注入在容器触发结构器的时候实现,该结构器有一系列的参数,每个参数代表注入的对象。
Setter 办法依赖注入:首先容器会触发一个无参构造函数或无参动态工厂办法实例化对象,之后容器调用 bean 中的 setter 办法实现 Setter 办法依赖注入。
17、你举荐哪种依赖注入?结构器依赖注入还是 Setter 办法依赖注入?
你能够同时应用两种形式的依赖注入,最好的抉择是应用结构器参数实现强制依赖注入,应用 setter 办法实现可选的依赖关系。
18、Spring IOC 如何实现
Spring 中的 org.springframework.beans 包和 org.springframework.context 包形成了 Spring 框架 IoC 容器的根底。
BeanFactory 接口提供了一个先进的配置机制,使得任何类型的对象的配置成为可能。
ApplicationContex接口对 BeanFactory(是一个子接口)进行了扩大,在 BeanFactory 的根底上增加了其余性能,比方与 Spring 的 AOP 更容易集成,也提供了解决 message resource 的机制(用于国际化)、事件流传以及应用层的特地配置,比方针对 Web 利用的 WebApplicationContext。
org.springframework.beans.factory.BeanFactory 是 Spring IoC 容器的具体实现,用来包装和治理后面提到的各种 bean。BeanFactory 接口是 Spring IoC 容器的外围接口。
19、Spring IoC 容器是什么?
Spring IOC 负责创建对象、治理对象(通过依赖注入)、整合对象、配置对象以及治理这些对象的生命周期。
20、IoC 有什么长处?
IOC 或依赖注入缩小了应用程序的代码量。它使得应用程序的测试很简略,因为在单元测试中不再须要单例或 JNDI 查找机制。简略的实现以及较少的烦扰机制使得松耦合得以实现。IOC 容器反对勤性单例及提早加载服务。
21、解释 AOP 模块
AOP 模块用来开发 Spring 应用程序中具备切面性质的局部。该模块的大部分服务由 AOP Aliance 提供,这就保障了 Spring 框架和其余 AOP 框架之间的互操作性。另外,该模块将元数据编程引入到了 Spring。
22、Spring 面向切面编程(AOP)
面向切面编程(AOP):容许程序员模块化横向业务逻辑,或定义外围局部的性能,例如日志治理和事务管理。
切面(Aspect):AOP 的外围就是切面,它将多个类的通用行为封装为可重用的模块。该模块含有一组 API 提供 cross-cutting 性能。例如, 日志模块称为日志的 AOP 切面。依据需要的不同,一个应用程序能够有若干切面。在 Spring AOP 中,切面通过带有 @Aspect 注解的类实现。
告诉(Advice):告诉示意在办法执行前后须要执行的动作。实际上它是 Spring AOP 框架在程序执行过程中触发的一些代码。Spring 切面能够执行一下五种类型的告诉:
before(前置告诉):在一个办法之前执行的告诉。after(最终告诉):当某连接点退出的时候执行的告诉(不论是失常返回还是异样退出)。after-returning(后置告诉):在某连接点失常实现后执行的告诉。after-throwing(异样告诉):在办法抛出异样退出时执行的告诉。around(盘绕告诉):在办法调用前后触发的告诉。
切入点 (Pointcut):切入点是一个或一组连接点,告诉将在这些地位执行。能够通过表达式或匹配的形式指明切入点。
引入:引入容许咱们在已有的类上增加新的办法或属性。
指标对象:被一个或者多个切面所告诉的对象。它通常是一个代理对象。也被称做被告诉(advised)对象。
代理:代理是将告诉利用到指标对象后创立的对象。从客户端的角度看,代理对象和指标对象是一样的。有以下几种代理:
BeanNameAutoProxyCreator:bean 名称主动代理创立器DefaultAdvisorAutoProxyCreator:默认告诉者主动代理创立器 Metadata autoproxying:元数据主动代理
织入:将切面和其余利用类型或对象连接起来创立一个告诉对象的过程。织入能够在编译、加载或运行时实现。
23、Spring AOP 实现原理
实现 AOP 的技术,次要分为两大类:
一是采纳 动静代理 技术,利用截取音讯的形式,对该音讯进行装璜,以取代原有对象行为的执行;二是采纳动态织入的形式,引入特定的语法创立“方面”,从而使得编译器能够在编译期间织入无关“方面”的代码。
Spring AOP 的实现原理其实很简略:AOP 框架负责动静地生成 AOP 代理类,这个代理类的办法则由 Advice 和回调指标对象的办法所组成, 并将该对象可作为指标对象应用。AOP 代理蕴含了指标对象的全副办法,但 AOP 代理中的办法与指标对象的办法存在差别,AOP 办法在特定切入点增加了加强解决,并回调了指标对象的办法。
Spring AOP 应用动静代理技术在运行期织入加强代码。应用两种代理机制:基于 JDK 的动静代理(JDK 自身只提供接口的代理)和基于 CGlib 的动静代理。
(1) JDK 的动静代理
JDK 的动静代理次要波及 java.lang.reflect 包中的两个类:Proxy 和 InvocationHandler。其中 InvocationHandler 只是一个接口,能够通过实现该接口定义横切逻辑,并通过反射机制调用指标类的代码,动静的将横切逻辑与业务逻辑织在一起。而 Proxy 利用 InvocationHandler 动态创建一个合乎某一接口的实例,生成指标类的代理对象。
其代理对象必须是某个接口的实现, 它是通过在运行期间创立一个接口的实现类来实现对指标对象的代理. 只能实现接口的类生成代理, 而不能针对类
(2)CGLib
CGLib 采纳底层的字节码技术,为一个类创立子类,并在子类中采纳办法拦挡的技术拦挡所有父类的调用办法,并趁势织入横切逻辑. 它运行期间生成的代理对象是指标类的扩大子类. 所以无奈告诉 final、private 的办法, 因为它们不能被覆写. 是针对类实现代理, 次要是为指定的类生成一个子类, 笼罩其中办法.
在 spring 中默认状况下应用 JDK 动静代理实现 AOP, 如果 proxy-target-class 设置为 true 或者应用了优化策略那么会应用 CGLIB 来创立动静代理.Spring AOP 在这两种形式的实现上根本一样.以 JDK 代理为例,会应用 JdkDynamicAopProxy 来创立代理,在 invoke()办法首先须要织入到以后类的增强器封装到拦截器链中,而后递归的调用这些拦截器实现性能的织入.最终返回代理对象.