目录
BeanFactory与ApplicationContext
后置处理器BeanPostProcessor 和 BeanFactoryPostProcessor
一、Spring概述
官网 : https://spring.io/
官方下载地址 : https://repo.spring.io/libs-release-local/org/springframework/spring/
GitHub : https://github.com/spring-projects
1.Spring 简介
Spring 是分层的 full-stack(全栈) 轻量级开源框架,以 IoC 和 AOP 为内核,提供了展现层 Spring MVC 和业务层事务管理等众多的企业级应⽤技术,还能整合开源世界众多著名的第三⽅框架和类库,已经成为使⽤最多的 Java EE 企业应⽤开源框架。我们经常说的 Spring 其实指的是Spring Framework(spring 框架)。
Spring 是一个开源应用框架,旨在降低应用程序开发的复杂度。
- 它是轻量级、松散耦合的。
它的轻量级主要是相对于 EJB 。随着 Spring 的体系越来越庞大,大家被 Spring 的配置搞懵逼了,所以后来出了 Spring Boot 。
- 它具有分层体系结构,允许用户选择组件,同时还为 J2EE 应用程序开发提供了一个有凝聚力的框架。
- 它可以集成其他框架,如 Spring MVC、Hibernate、MyBatis 等,所以又称为框架的框架( 粘合剂、脚手架 )。
一句话概括:Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器(框架)。
2.Spring 发展历程
1997年 IBM 提出了EJB的思想; 1998年,SUN 制定开发标准规范EJB1.0; 1999年,EJB 1.1发 布; 2001年,EJB 2.0发布; 2003年,EJB 2.1发布; 2006年,EJB 3.0发布;
Rod Johnson(spring之⽗)
- Expert One-to-One J2EE Design and Development(2002) 阐述了J2EE使⽤EJB开发设计的优点及解决⽅案
- Expert One-to-One J2EE Development without EJB(2004) 阐述了J2EE开发不使⽤EJB的解决 ⽅式(Spring雏形)
2017 年 9 ⽉份发布了 Spring 的最新版本 Spring 5.0 通⽤版(GA)
3.Spring的优点
- 方便解耦,简化开发 (高内聚低耦合)
Spring就是一个大工厂(容器),可以将所有对象创建和依赖关系维护,交给Spring管理
spring工厂是用于生成bean - AOP编程的支持
Spring提供面向切面编程,可以方便的实现对程序进行权限拦截、运行监控等功能 - 声明式事务的支持
只需要通过配置就可以完成对事务的管理,而无需手动编程 - 方便程序的测试
Spring对Junit4支持,可以通过注解方便的测试Spring程序 - 方便集成各种优秀框架
Spring不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(如:Struts、Hibernate、MyBatis、Quartz等)的直接支持 - 降低JavaEE API的使用难度
Spring 对JavaEE开发中非常难用的一些API(JDBC、JavaMail、远程调用等),都提供了封装,使这些API应用难度大大降低
4.Spring组成
如下是一张比较早期版本的 Spring Framework 的模块图:
Spring 核心容器(Core Container):该层基本上是 Spring Framework 的核心。它包含以下模块:
- Spring Core
-
Spring Bean:核心容器提供 Spring 框架的基本功能。核心容器的主要组件是 BeanFactory,它是工厂模式的实现。BeanFactory 使用控制反转 (IOC)模式将应用程序的配置和依赖性规范与实际的应用程序代码分开。
-
Spring Context :Spring 上下文是一个配置文件,向 Spring 框架提供上下文信息。Spring 上下文包括企业服务,例如 JNDI、EJB、电子邮件、国际化、事件机制、校验和调度功能。
-
SpEL (Spring Expression Language):Spring 表达式语言全称为 “Spring Expression Language”,缩写为 “SpEL” ,类似于 Struts2 中使用的 OGNL 表达式语言,能在运行时构建复杂表达式、存取对象图属性、对象方法调用等等,并且能与 Spring 功能完美整合,如能用来配置 Bean 定义。或者说,这块就是 Spring IoC 。
数据访问(Data Access):该层提供与数据库交互的支持。它包含以下模块
- JDBC (Java DataBase Connectivity):Spring 对 JDBC 的封装模块,提供了对关系数据库的访问。
- ORM (Object Relational Mapping):Spring ORM 模块,提供了对 hibernate5 和 JPA 的集成。
- OXM (Object XML Mappers):
- Transaction:Spring 简单而强大的事务管理功能,包括声明式事务和编程式事务。
Web:该层提供了创建 Web 应用程序的支持。它包含以下模块
- WebMVC:MVC 框架是一个全功能的构建 Web 应用程序的 MVC 实现。通过策略接口,MVC 框架变成为高度可配置的,MVC 容纳了大量视图技术,其中包括 JSP、Velocity、Tiles、iText 和 POI。
- WebFlux:基于 Reactive 库的响应式的 Web 开发框架
- WebSocket:Spring 4.0 的一个最大更新是增加了对 Websocket 的支持。Websocket 提供了一个在 Web 应用中实现高效、双向通讯,需考虑客户端(浏览器)和服务端之间高频和低延时消息交换的机制。一般的应用场景有:在线交易、网页聊天、游戏、协作、数据可视化等。
AOP:该层支持面向切面编程。它包含以下模块:
- AOP:通过配置管理特性,Spring AOP 模块直接将面向方面的编程功能集成到了 Spring 框架中。所以,可以很容易地使 Spring 框架管理的任何对象支持 AOP。Spring AOP 模块为基于 Spring 的应用程序中的对象提供了事务管理服务。通过使用 Spring AOP,不用依赖 EJB 组件,就可以将声明性事务管理集成到应用程序中。
- Aspects:该模块为与 AspectJ 的集成提供支持
- Instrumentation:该层为类检测和类加载器实现提供支持,用的比较少
其它
- JMS (Java Messaging Service):提供了一个 JMS 集成框架,简化了 JMS API 的使用
- Test:该模块为使用 JUnit 和 TestNG 进行测试提供支持。
- Messaging:该模块为 STOMP 提供支持。它还支持注解编程模型,该模型用于从 WebSocket 客户端路由和处理 STOMP 消息。
Spring 框架是一个分层架构,由 7 个定义良好的模块组成。Spring 模块构建在核心容器之上,核心容器定义了创建、配置和管理 bean 的方式 .
组成 Spring 框架的每个模块(或组件)都可以单独存在,或者与其他一个或多个模块联合实现。每个模块的功能如下:
- 核心容器:核心容器提供 Spring 框架的基本功能。核心容器的主要组件是 BeanFactory,它是工厂模式的实现。BeanFactory 使用控制反转(IOC) 模式将应用程序的配置和依赖性规范与实际的应用程序代码分开。
- Spring 上下文:Spring 上下文是一个配置文件,向 Spring 框架提供上下文信息。Spring 上下文包括企业服务,例如 JNDI、EJB、电子邮件、国际化、校验和调度功能。
- Spring AOP:通过配置管理特性,Spring AOP 模块直接将面向切面的编程功能 , 集成到了 Spring 框架中。所以,可以很容易地使 Spring 框架管理任何支持 AOP的对象。Spring AOP 模块为基于 Spring 的应用程序中的对象提供了事务管理服务。通过使用 Spring AOP,不用依赖组件,就可以将声明性事务管理集成到应用程序中。
- Spring DAO:JDBC DAO 抽象层提供了有意义的异常层次结构,可用该结构来管理异常处理和不同数据库供应商抛出的错误消息。异常层次结构简化了错误处理,并且极大地降低了需要编写的异常代码数量(例如打开和关闭连接)。Spring DAO 的面向 JDBC 的异常遵从通用的 DAO 异常层次结构。
- Spring ORM:Spring 框架插入了若干个 ORM 框架,从而提供了 ORM 的对象关系工具,其中包括 JDO、Hibernate 和 iBatis SQL Map。所有这些都遵从 Spring 的通用事务和 DAO 异常层次结构。
- Spring Web 模块:Web 上下文模块建立在应用程序上下文模块之上,为基于 Web 的应用程序提供了上下文。所以,Spring 框架支持与 Jakarta Struts 的集成。Web 模块还简化了处理多部分请求以及将请求参数绑定到域对象的工作。
- Spring MVC 框架:MVC 框架是一个全功能的构建 Web 应用程序的 MVC 实现。通过策略接口,MVC 框架变成为高度可配置的,MVC 容纳了大量视图技术,其中包括 JSP、Velocity、Tiles、iText 和 POI。
二、Spring核心思想
1、IOC控制反转
什么是IOC
即控制权的转移,将我们创建对象的方式反转了,以前对象的创建是由我们开发人员自己维护,包括依赖关系也是自己注入。使用了spring之后,对象的创建以及依赖关系可以由spring完成创建以及注入,反转控制就是反转了对象的创建方式,从我们自己创建反转给了程序创建(spring)
- 控制:指的是对象创建(实例化、管理)的权利
- 反转:控制权交给外部环境了(spring框架、IoC容器)
IoC解决了什么问题
IoC解决对象之间的耦合问题
IoC和DI的区别
DI:Dependancy Injection(依赖注⼊)
spring这个容器中,替你管理着一系列的类,前提是你需要将这些类交给spring容器进行管理,然后在你需要的时候,不是自己去定义,而是直接向spring容器索取,当spring容器知道你的需求之后,就会去它所管理的组件中进行查找,然后直接给你所需要的组件.
实现IOC思想需要DI做支持
注入方式: 1.set方式注入 2.构造方法注入 3.字段注入
注入类型: 1.值类型注入 2.引用类型注入
IOC和DI描述的是同⼀件事情,只不过⻆度不⼀样罢了
好处
1.将对象集中统一管理,便于修改和配置
2.降低组件之间的耦合度,实现软件各层之间的解耦.
3.可以使容器提供众多服务如事务管理消息服务处理等等。当我们使用容器管理事务时,开发人员就不需要手工 控制事务,也不需要处理复杂的事务传播
4.容器提供单例模式支持,开发人员不需要自己编写实现代码.
5.容器提供了AOP技术,利用它很容易实现如权限拦截,运行期监控等功能
6.容器提供众多的辅佐类,使这些类可以加快应用的开发.如jdbcTemplate HibernateTemplate
2、AOP
什么是AOP
AOP(Aspect Oriented Programming)意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
Spring AOP主要做的事情就是:「把重复的代码抽取,在运行的时候往业务方法上动态植入“切面类代码”」
AOP在解决什么问题
在不改变原有业务逻辑情况下,增强横切逻辑代码,根本上解耦合,避免横切逻辑代码重复
AOP中的名词
- 横切关注点:跨越应用程序多个模块的方法或功能。即是,与我们业务逻辑无关的,但是我们需要关注的部分,就是横切关注点。如日志 , 安全 , 缓存 , 事务等等 …
- 切面(ASPECT):横切关注点 被模块化 的特殊对象。即,它是一个类。
- 通知(Advice):切面必须要完成的工作。即,它是类中的一个方法。
- 目标(Target):被通知对象。
- 代理(Proxy):向目标对象应用通知之后创建的对象。
- 切入点(PointCut):切面通知 执行的 “地点”的定义。
- 连接点(JointPoint):与切入点匹配的执行点。
SpringAOP中,通过Advice定义横切逻辑,Spring中支持5种类型的Advice:
三、Spring IOC应用
1.Spring IOC基础
BeanFactory与ApplicationContext
BeanFactory是Spring框架中IoC容器的顶层接⼝,它只是⽤来定义⼀些基础功能,定义⼀些基础规范,⽽ ApplicationContext是它的⼀个⼦接⼝,所以ApplicationContext是具备BeanFactory提供的全部功能的。
通常,我们称BeanFactory为SpringIOC的基础容器,ApplicationContext是容器的⾼级接⼝,⽐ BeanFactory要拥有更多的功能,⽐如说国际化⽀持和资源访问(xml,java配置类)等等
总结:
二者是父子关系。Spring的IoC容器就是一个实现了BeanFactory接口的可实例化类,它就是 Spring IoC 容器的真面目。ioc使用 BeanFactory 来实例化、配置和管理 Bean。
如果说BeanFactory是Spring的心脏,那么ApplicationContext就是完整的躯体了,ApplicationContext由BeanFactory派生而来,提供了更多面向实际应用的功能。
(1)MessageSource, 提供国际化的消息访问
(2)资源访问,如URL和文件
(3)事件传播特性,即支持aop特性
1.ApplicationContext接口继承BeanFactory接口,Spring核心工厂是BeanFactory ,BeanFactory采取延迟加载,第一次getBean时才会初始化Bean, ApplicationContext是会在加载配置文件时初始化Bean。
2.ApplicationContext是对BeanFactory扩展,他可以国际化处理、资源访问、事件传播。
启动 IoC 容器的⽅式
(1)Java环境下启动IoC容器
- ClassPathXmlApplicationContext:从类的根路径下加载配置⽂件(推荐使⽤)
- FileSystemXmlApplicationContext:从磁盘路径上加载配置⽂件
- AnnotationConfigApplicationContext:纯注解模式下启动Spring容器
(2)Web环境下启动IoC容器
- 从xml启动容器
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
<!--配置Spring ioc容器的配置⽂件-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!--使⽤监听器启动Spring的IOC容器-->
<listener>
<listenerclass>org.springframework.web.context.ContextLoaderListener</listenerclass>
</listener>
</web-app>
- 从配置类启动容器
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
<!--告诉ContextloaderListener知道我们使⽤注解的⽅式启动ioc容器-->
<context-param>
<param-name>contextClass</param-name>
<paramvalue>org.springframework.web.context.support.AnnotationConfigWebAppli
cationContext</param-value>
</context-param>
<!--配置启动类的全限定类名-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>com.lagou.edu.SpringConfig</param-value>
</context-param>
<!--使⽤监听器启动Spring的IOC容器-->
<listener>
<listenerclass>org.springframework.web.context.ContextLoaderListener</listenerclass>
</listener>
</web-app>
Bean的生命周期
建立
1 . Bean的建立
由BeanFactory读取Bean定义文件,并生成各个实例。
初始化
2 . 依赖注入
3.setBeanName()
4.setBeanFactory()
5.processBeforeInitialization()
初始化之前都会执行这个实例的processBeforeInitialization()方法。
6.afterPropertiesSet()
7.init-method
8.processAfterInitialization()
业务逻辑
9.使用Bean做一些业务逻辑
销毁
10.destroy()
11.destroy-method
Spring实例化bean的三种方法与标签属性
⽅式⼀:使⽤⽆参构造函数。在默认情况下,它会通过反射调⽤⽆参构造函数来创建对象。如果类中没有⽆参构造函数,将创建失败。
<bean id="exampleBean" class="examples.ExampleBean"/>
⽅式⼆:使⽤静态⽅法创建
<bean id="exampleBean" class="examples.ExampleBean" factory-method="静态方法"/>
⽅式三:使⽤实例化⽅法创建
<bean id="serviceLocator" class="examples.DefaultServiceLocator">
<bean id="clientService" factory-bean="serviceLocator" factory-method="createClientServiceInstance"/>
Bean的参数有id、class、factory-bean、factory-method等
- id属性: ⽤于给bean提供⼀个唯⼀标识。在⼀个标签内部,标识必须唯⼀。
- class属性:⽤于指定创建Bean对象的全限定类名。
- name属性:⽤于给bean提供⼀个或多个名称。多个名称⽤空格分隔。
- factory-bean属性:⽤于指定创建当前bean对象的⼯⼚bean的唯⼀标识。当指定了此属性之后, class属性失效。
- factory-method属性:⽤于指定创建当前bean对象的⼯⼚⽅法,如配合factory-bean属性使⽤, 则class属性失效。如配合class属性使⽤,则⽅法必须是static的。
- scope属性:⽤于指定bean对象的作⽤范围。通常情况下就是singleton。当要⽤到多例模式时, 可以配置为prototype。
- init-method属性:⽤于指定bean对象的初始化⽅法,此⽅法会在bean对象装配后调⽤。必须是 ⼀个⽆参⽅法。
- destory-method属性:⽤于指定bean对象的销毁⽅法,此⽅法会在bean对象销毁前执⾏。它只能为scope是singleton时起作⽤。
Servlet生命周期
- 初始化阶段 调用init()方法
- 响应客户请求阶段 调用service()方法
- 终止阶段 调用destroy()方法
Bean的作用范围及⽣命周期
在spring框架管理Bean对象的创建时,Bean对象默认都是单例的,但是它⽀持配置的⽅式改 变作⽤范围。作⽤范围官⽅提供的说明如下图:
在上图中提供的这些选项中,我们实际开发中⽤到最多的作⽤范围就是singleton(单例模式)和 prototype(原型模式,也叫多例模式)。配置⽅式参考下⾯的代码:
<!--配置service对象-->
<bean id="bean" class="example.bean" scope="singleton"></bean>
1) Singleton: 这是默认的作用域,这种范围确保不管接受多少个请求,每个容器中只有一个bean的实例,单例模式有BeanFactory自身维护;
2) Prototype: 原形范围与单例范围相反,为每一个bean请求提供一个实例;
3) Request: 在请求bean范围内会为每一个来自客户端的网络请求创建一个实例,在请求完成以后,bean会失效并被垃圾回收器回收;
4) Session: 与请求范围类似,确保每个session中有一个bean的实例,在session过期后,bean会随之失效;
DI 依赖注⼊
(1)分类
①按照注⼊的⽅式分类
-
构造函数注⼊:顾名思义,就是利⽤带参构造函数实现对类成员的数据赋值。
<bean id="user" class="com.zcl.spring.setterinjection.User">
<constructor-arg value="Zhao" />
<constructor-arg value="22" />
<constructor-arg value="China" />
</bean>
-
set⽅法注⼊:它是通过类成员的set⽅法实现数据的注⼊。(使⽤最多的)
<bean id="user" class="com.zcl.spring.setterinjection.User">
<property name="name" value="Zhao" />
<property name="age" value="22" />
<property name="country" value="China" />
</bean>
设值注入优点
一、与传统的JavaBean的写法更相似,程序开发人员更容易理解、接受,依赖关系显得更加直观、自然。
二、对于复杂的依赖关系,如果采用构造注入,会导致构造器过于臃肿,难以阅读。而设值注入不会
三、在某些属性可选的情况下,多参数的构造器更加笨重。
构造注入优点
一、构造注入可以在构造器中决定依赖关系的注入顺序,优先依赖的优先注入。
二、对于依赖关系无须变化的Bean,构造注入更有用处。
建议:采用设值注入为主,构造注入为辅的注入策略。对于依赖关系无需变化的注入,尽量采用构造注入;而其它的依赖关系的注入,则考虑设值注入。
②按照注⼊的数据类型分类
-
基本类型和String: 注⼊的数据类型是基本类型或者是字符串类型的数据。
-
其他Bean类型 注⼊的数据类型是对象类型,称为其他Bean的原因是,这个对象是要求出现在IoC容器 中的。那么针对当前Bean来说,就是其他Bean了。
-
复杂类型(集合类型) 注⼊的数据类型是Aarry,List,Set,Map,Properties中的⼀种类型。
2.Spring IOC⾼级特性
lazy-Init 延迟加载
Bean的延迟加载(延迟创建) ApplicationContext 容器的默认⾏为是在启动服务器时将所有 singleton bean 提前进⾏实例化。提前 实例化意味着作为初始化过程的⼀部分,ApplicationContext 实例会创建并配置所有的singleton bean
如果不想让⼀个singleton bean 在 ApplicationContext实现初始化时被提前实例化,那么可以将bean 设置为延迟实例化。
<bean id="testBean" calss="cn.LazyBean" lazy-init="true" />
如果⼀个设置了⽴即加载的 bean1,引⽤了⼀个延迟加载的 bean2 ,那么 bean1 在容器启动时被实例 化,⽽ bean2 由于被 bean1 引⽤,所以也被实例化,这种情况也符合延时加载的 bean 在第⼀次调⽤ 时才被实例化的规则。
也可以在容器层次中通过在 元素上使⽤ "default-lazy-init" 属性来控制延时初始化。如下⾯配置:
<beans default-lazy-init="true">
<!-- no beans will be eagerly pre-instantiated... -->
</beans>
如果⼀个 bean 的 scope 属性为 scope="pototype" 时,即使设置了 lazy-init="false",容器启动时也不 会实例化bean,⽽是调⽤ getBean ⽅法实例化的。
lazy-Init 延迟加载应用场景
-
开启延迟加载⼀定程度提⾼容器启动和运转性能
-
对于不常使⽤的 Bean 设置延迟加载,这样偶尔使⽤的时候再加载,不必要从⼀开始该 Bean 就占⽤资源
-
⽗Bean应⽤泛型,当类实例化时通过反射来确定具体类型: 需要设置⽗Bean为延迟加载
FactoryBean 和 BeanFactory
BeanFactory接⼝是容器的顶级接⼝,定义了容器的⼀些基础⾏为,负责⽣产和管理Bean的⼀个⼯⼚, 具体使⽤它下⾯的⼦接⼝类型,⽐如ApplicationContext;此处我们重点分析FactoryBean
Spring中Bean有两种,⼀种是普通Bean,⼀种是⼯⼚Bean(FactoryBean),FactoryBean可以⽣成 某⼀个类型的Bean实例(返回给我们),也就是说我们可以借助于它⾃定义Bean的创建过程。
后置处理器BeanPostProcessor 和 BeanFactoryPostProcessor
BeanPostProcessor是针对Bean级别的处理,可以针对某个具体的Bean.
定义⼀个类实现了BeanPostProcessor,默认是会对整个Spring容器中所有的bean进⾏处理。如果要对 具体的某个bean处理,可以通过⽅法参数判断,两个类型参数分别为Object和String,第⼀个参数是每 个bean的实例,第⼆个参数是每个bean的name或者id属性的值。所以我们可以通过第⼆个参数,来判 断我们将要处理的具体的bean。 注意:处理是发⽣在Spring容器的实例化和依赖注⼊之后。
BeanFactoryPostProcessor是针对整个Bean的⼯⼚进⾏处理,典型应⽤:PropertyPlaceholderConfigurer
四、Spring AOP应用
1.Spring事物管理简单介绍
包括声明式事务和编程式事务,编程式的,比较灵活,但是代码量大,存在重复的代码比较多;声明式的比编程式的更灵活,最大的好处是大大减少了代码量。编程式不常用,接下来介绍声明式事务管理。
声明式事务管理建立在AOP之上的,动态代理实现其机制(不改变源码,对原有的功能动态扩展)。声明式事务管理使业务代码不受污染,这正是spring倡导的非侵入式的开发方式。声明式事物处理也有五种不同的配置方式,单常用的是基于 @Transactional注解的声明式事务管理。此时在DAO上需加上@Transactional注解,在需要事务处理的类或方法上都可以加。
Spring配置文件中关于事务配置总是由三个组成部分,分别是DataSource、TransactionManager和代理机制这三部分,无论哪种配置方式,一般变化的只是代理机制这部分。
TransactionDefinition接口定义了四种事物属性是我们需要知道的
事物传播行为
在开始当前事务之前,一个事务上下文已经存在,此时有若干选项可以指定一个事务性方法的执行行为。
-
TransactionDefinition.PROPAGATION_REQUIRED:如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。这是默认值。
-
TransactionDefinition.PROPAGATION_REQUIRES_NEW:创建一个新的事务,如果当前存在事务,则把当前事务挂起。
-
TransactionDefinition.PROPAGATION_SUPPORTS:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。
-
TransactionDefinition.PROPAGATION_NOT_SUPPORTED:以非事务方式运行,如果当前存在事务,则把当前事务挂起。
-
TransactionDefinition.PROPAGATION_NEVER:以非事务方式运行,如果当前存在事务,则抛出异常。
-
TransactionDefinition.PROPAGATION_MANDATORY:如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。
-
TransactionDefinition.PROPAGATION_NESTED:如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该取值等价于TransactionDefinition.PROPAGATION_REQUIRED。
事物隔离级别
-
TransactionDefinition.ISOLATION_DEFAULT:这是默认值,表示使用底层数据库的默认隔离级别。对大部分数据库而言,通常这值就是TransactionDefinition.ISOLATION_READ_COMMITTED。
-
TransactionDefinition.ISOLATION_READ_UNCOMMITTED:该隔离级别表示一个事务可以读取另一个事务修改但还没有提交的数据。该级别不能防止脏读,不可重复读和幻读,因此很少使用该隔离级别。比如PostgreSQL实际上并没有此级别。
-
TransactionDefinition.ISOLATION_READ_COMMITTED:该隔离级别表示一个事务只能读取另一个事务已经提交的数据。该级别可以防止脏读,这也是大多数情况下的推荐值。
-
TransactionDefinition.ISOLATION_REPEATABLE_READ:该隔离级别表示一个事务在整个过程中可以多次重复执行某个查询,并且每次返回的记录都相同。该级别可以防止脏读和不可重复读。
-
TransactionDefinition.ISOLATION_SERIALIZABLE:所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。但是这将严重影响程序的性能。通常情况下也不会用到该级别。
事务超时
-
所谓事务超时,就是指一个事务所准许实行的最长时辰,假定跨越该时辰限制但事务还没有完成,则自动回滚事务。
事务只读属性
-
只读事务用于客户代码只读但不修改数据的情形,只读事务用于特定情景下的优化,比如使用Hibernate的时候。
精选面试题
1.Spring 框架中都用到了哪些设计模式?
-
代理模式 — 在 AOP 和 remoting 中被用的比较多。
-
单例模式 — 在 Spring 配置文件中定义的 Bean 默认为单例模式。
-
模板方法 — 用来解决代码重复的问题。比如 RestTemplate、JmsTemplate、JdbcTemplate 。
-
前端控制器 — Spring提供了 DispatcherServlet 来对请求进行分发。
-
视图帮助(View Helper) — Spring 提供了一系列的 JSP 标签,高效宏来辅助将分散的代码整合在视图里。
-
依赖注入 — 贯穿于 BeanFactory / ApplicationContext 接口的核心理念。
-
工厂模式 — BeanFactory 用来创建对象的实例。
参考文章
附:Spring知识点总结思维导图