Spring概述
Spring介绍
Spring它是一个一站式的分层轻量级框架。php
Spring体系结构
1. core containercss
a) beans与core 它们提供spring框架最基本功能,包含ioc与dihtml
b) context 上下文对象,基于beans与coresjava
c) spel它是sprng提供的一个表达式语言web
2. Data access/integration面试
a) 数据访问正则表达式
b) 集成spring
3. Websql
a) Spring自己提供springmvc数据库
b) 也能够与其它的web层进行集成
4. AOP
AOP大部分状况下是使用动态代理来实现的。
5. Test
使用spring能够方便的进行测试
Spring框架优势
n 方便解耦,简化开发
Spring就是一个大工厂,能够将全部对象建立和依赖关系维护,交给Spring管理
n AOP编程的支持
Spring提供面向切面编程,能够方便的实现对程序进行权限拦截、运行监控等功能
n 声明式事务的支持
只须要经过配置就能够完成对事务的管理,而无需手动编程
n 方便程序的测试
Spring对Junit4支持,能够经过注解方便的测试Spring程序
n 方便集成各类优秀框架
Spring不排斥各类优秀的开源框架,其内部提供了对各类优秀框架(如:Struts、Hibernate、MyBatis、Quartz等)的直接支持
n 下降JavaEE API的使用难度
Spring 对JavaEE开发中很是难用的一些API(JDBC、JavaMail、远程调用等),都提供了封装,使这些API应用难度大大下降
IOC与DI
Spring的jar包下载
Spring的官网:spring.io
咱们课程中讲解使用的是spring4.2.4
在spring3.0.2版本后,不在提供依赖jar包
docs 存在API和规范文档
libs 开发jar包
schema 开发过程当中须要的xml的schema约束
spring开发环境搭建
在spring开发中,咱们要根据不一样的状况来导入不一样的jar包,当前咱们要讲解的是关于ioc与di
对于ioc与di讲解咱们只须要使用spring的核心功能。
1. beans相关
2. core相关
3. context相关
4. spel相关
咱们使用spring框架也会使用到配置文件,咱们须要在src下建立一个关于spring的配置文件,通常状况名称叫applicationContext.xml
问题:applicationContext.xml约束?
它的路径:
spring-framework-4.2.4.RELEASE-dist\spring-framework-4.2.4.RELEASE\docs\spring-framework-reference\html
IOC快速入门
Ioc它是什么,解决什么问题,它的原理是如何实现。
IOC inversion ofController 控制反转。
在程序中所说的IOC其实简单说,就是原来由咱们本身实例化的对象交给spring容器来实始化。这时对象的实始化的权利就会反转。
程序运行时报错
缘由:当前环境须要一个commons-loggin的jar包
总结spring使用步骤:
1. 在applicationContext.xml文件中配置bean
2. 建立一个AppliCationContext对象
ApplicationContext它是BeanFactory的一个子接口,咱们在使用时使用的是AppliCationContext的实现类ClassPathXmlApplicationContext
能够经过getBean(配置文件中id名称)来获取指定的对象。
DI
DI:dependencyinjection 依赖注入
在spring框架负责建立Bean对象时,动态将依赖对象注入到Bean组件。
简单说,这时UserServiceImpl中的info属性值就是ITCAST
面试题:IOC和DI区别?
IOC控制反转,是指对象实例化权利由spring容器来管理
DI依赖注入 在spring建立对象的过程当中,对象所依赖的属性经过配置注入对象中。
Bean获取与实例化
ApplicationContext与BeanFactory关系
ApplicationContext它是扩展BeanFactory接口。
BeanFactory它采起延迟加载的方案,只有真正在getBean时才会实例化Bean
在开发中咱们通常使用的是ApplicationContext,真正使用的是其实现类,
FileSystemXmlAppliCationContext 根据文件路径获取
ClassPathXmlApplicationContext 根据类路径获取
AppliCationContext它会在配置文件加载时,就会初始化Bean,而且ApplicationContext它提供不一样的应用层的Context实现。例如在web开发中可使用WebApplicationContext.
Bean的实例化方式
无参数构造
对于这种方式,注意Bean类中必须提供无参数构造。
静态工厂方法
须要建立一个工厂类,在工厂类中提供一个static返回bean对象的方法就能够。
实例工厂方法
须要建立一个工厂类,在工厂类中提供一个非static的建立bean对象的方法,在配置文件中须要将工厂配置,还须要配置bean
Bean的做用域
在bean声明时它有一个scope属性,它是用于描述bean的做用域。
可取值有:
singleton:单例 表明在spring ioc容器中只有一个Bean实例 (默认的scope)
prototype多例 每一次从spring容器中获取时,都会返回一个新的实例
request用在web开发中,将bean对象request.setAttribute()存储到request域中
session用在web开发中,将bean对象session.setAttribute()存储到session域中
在开如经常使用的值是singleton与prototype
Bean的生命周期
1. instantiate bean对象实例化
2. populate properties 封装属性
3. 若是Bean实现BeanNameAware执行setBeanName
4. 若是Bean实现BeanFactoryAwar或ApplicationContextAwar设置工厂setBeanFactory或上下文对象setApplicationContext
5. 若是存在类实现BeanPostProcessor(后处理Bean),执行postProcessBeforeInitialization
6. 若是Bean实现InitializingBean执行afterPropertiesSet
7. 调用自定义的init-method方法
8. 若是存在类实现BeanPostProcessor(处理Bean),执行postProcessAfterInitialization
9. 执行业务处理
10. 若是Bean实现DisposableBean执行destroy
11. 调用自定义的destroy-method
对于bean的生命周期方法:
第三步与第四步是让Bean了解spring容器。
第五步与第八步能够针对指定的Bean进行功能加强,这时通常会使用动态代理.
第六步与第十步:经过实现指定的接口来完成init与destroy操做
可是在开发中通常不使用第6步与第10步,缘由是咱们可使用第7步与第11步来完成。
第7步与第11步的初始化与销毁操做它无耦合,推荐使用的。可是必须在配置文件中指定初始化与销毁的方法
总结:
对于bean的生命周期,咱们须要关注的主要有两个方法:
1. 加强bean的功能可使用后处理Bean, BeanPostProcessor
2. 若是须要初始化或销毁操做咱们可使用init-method destroy-method
注意:destroy-method只对scope=singleton有效果。
Bean的属性注入
在spring中bean的属性注入有两种
构造器注入
Setter方法注入
关于ref属性做用
使用ref来引入另外一个bean对象,完成bean之间注入
集合属性的注入
在spring中对于集合属性,可使用专门的标签来完成注入例如:list set map properties等集合元素来完成集合属性注入.
List属性注入
若是属性是数组类型也可使用list完成注入
Set属性注入
Map属性注入
Properties属性注入
Java.util.Properties是java.utilsMap的实现类,它的key与value都是String类型.
名称空间p和c的使用
Spring2.0之后提供了xml命名空间。
P名称空间
C名称空间
首先它们不是真正的名称空间,是虚拟的。它是嵌入到spring内核中的。
使用p名称空间能够解决咱们setter注入时<property>简化
使用c名称空间能够解决咱们构造器注入时<constructor-arg>简化
使用setter注入
在applicationContext.xml文件中添加p名称空间简化setter注入
使用c名称空间来解决构造器注入
在applicationContext.xml文件中添加c名称空间
注:若是c或p名称空间操做的属性后缀是”-ref”表明要引入另外一个已经存在的bean,例如
SpEl
spring expression language 是在spring3.0之后的版本提供
它相似于ognl或el表达式,它能够提供在程序运行时构造复杂表达式来完成对象属性存储及方法调用等。
Spel表达式的格式 #{表达式}
示例1:完成bean之间的注入
示例2 支持属性调用及方法调用
Spring注解开发
在spring中使用注解,咱们必须在applicationContext.xml文件中添加一个标签
<context:annotation-config/>做用是让spring中经常使用的一些注解生效。
要使用contex名称空间,必须在applicationContext.xml文件中引入
完成bean注册操做
@Component
测试时报错
缘由:若是你使用的是spring3.x那么不会出现这个错误,若是使用的是spring4.x会报错,缘由是缺乏jar包。
导入jar后运行还有错误
咱们在applicationContext.xml文件中使用了一个标签 <context:annotation-config/>,它表明的是可使用spring的注解,可是咱们在类上添加的注解,spring不知道位置。
要解决这个问题,咱们可使用<context:component-sacn base-package=””>
在spring2.5后为@Component添加了三个衍生的注解
@Rpository 用于DAO层
@Service 用于service层
@Controller 用于表现层
对于咱们的bean所处在的位置能够选择上述三个注解来应用,若是你的bean不明确位置,就可使用@Component.
属性依赖注入
1. 简单的属性注入
2. 复杂的属性注入
注意:若是要扫描多个包下的注解能够写成如下:
或
注意:@Value @Autowired它们能够修饰属性,也能够修饰setter方法,若是写在属性上,就不须要提供setter方法。
@Autowired它默认是根据类型进行注入。
若是与@Qualifier一块儿使用,就能够根据名称来进行注入。
咱们也可使用下面的方式来根据名称进行属性注入
其它注解
@Scope它以描述bean的做用域。
它至关于init-method=”myInit
它至关因而destroy-method=”myDestroy”
注意:对于销毁的方法它只对bean的scope=singleton有效。
Spring在web开发中的应用
1.,在web项目中要使用spring须要导入一个jar包
2.在web.xml文件中配置Listener
这个ContextLoaderListener它实现了ServletContextListener
在这个listener中,当服务器启动时,将ApplicationContext对象,实际上是它的一个实现类
WebApplicationContext,对象存入到了ServletContext中。
3.咱们还须要在web.xml文件中配置applicationContext.xml文件的位置
默认状况下会在WEB-INF目录 下查找applicationContext.xmls
若是applicationContext.xml文件不是在默认位置,咱们能够在web.xml文件中配置
Classpath:applicationContext.xml 它表明的是在当前工程的类路径下(能够理解成是在src)下来查找applicationContext.xml文件。
contextConfigLocation它是在listener中声明的一个常量,描述的就是spring配置文件的位置。
Spring整合junit4测试
Spring整合junit4能够方便咱们的测试。
1. 须要导入一个spring-test.jar包
2. 能够在测试类上以下操做
Spring AOP
AOP概述
在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,经过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP能够对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度下降,提升程序的可重用性,同时提升了开发的效率。
AOP是一个概念,并无设定具体语言的实现,它能克服那些只有单继承特性语言的缺点,spring2.0以后整合AspectJ第三方AOP技术。
AspectJ是一个面向切面的框架,它扩展了Java语言。AspectJ定义了AOP语法因此它有一个专门的编译器用来生成遵照Java字节编码规范的Class文件。
主要功能
日志记录,性能统计,安全控制,事务处理,异常处理等等
主要意图
将日志记录,性能统计,安全控制,事务处理,异常处理等代码从业务逻辑代码中划分出来,经过对这些行为的分离,咱们但愿能够将它们独立到非指导业务逻辑的方法中,进而改变这些行为的时候不影响业务逻辑的代码。
AOP与OOP区别
OOP(面向对象编程)针对业务处理过程的实体及其属性和行为进行抽象封装,以得到更加清晰高效的逻辑单元划分。
而AOP则是针对业务处理过程当中的切面进行提取,它所面对的是处理过程当中的某个步骤或阶段,以得到逻辑过程当中各部分之间低耦合性的隔离效果。这两种设计思想在目标上有着本质的差别。
换而言之,OOD/OOP面向名词领域,AOP面向动词领域。
AOP相关术语
目标对象target
指的是须要被加强的对象,因为spring aop是经过代理模式实现,从而这个对象永远是被代理对象。
链接点(join point)
所谓链接点是指那些被拦截到的点,在spring中这些点指的是方法,由于spring只支持方法类型的链接点
切入点(pointcut)
表示一组 joint point,这些 joint point 或是经过逻辑关系组合起来,或是经过通配、正则表达式等方式集中起来,它定义了相应的 Advice 将要发生的地方
简单说切入点是指咱们要对哪些链接点进行拦截的定义
通知(advice)
所谓通知是指拦截到链接点以后所要作的事情就是通知,通知分为前置通知,后置通知,异常通知,最终通知,环绕通知
Advice 定义了在 pointcut 里面定义的程序点具体要作的操做
引介introduction
引介是一种特殊的通知,在不修改类代码的前提下,introduction能够在运行期为类动态地添加一些方法或属性
切面aspect
是切入点和通知的结合
织入weaving
织入是一个过程,是将切面应用到目标对象从而建立出AOP代理对象的过程,织入能够在编译期,类装载期,运行期进行。
Spring采用动态织入,而aspectj采用静态织入
代理Proxy
一个类被AOP织入加强后,就产生一个结果代理类
AOP底层实现
AOP分为静态AOP和动态AOP。静态AOP是指AspectJ实现的AOP,他是将切面代码直接编译到Java类文件中。动态AOP是指将切面代码进行动态织入实现的AOP。Spring的AOP为动态AOP,实现的技术为: JDK提供的动态代理技术 和 CGLIB(动态字节码加强技术)
JDK动态代理
在运行,在JVM内部动态生成class字节码对象(Class对象)
Jdk动态代理只针对于接口操做
第一个参数:目标类的类加载器对象
第二个参数:目标类的实现接口的Class[]
第三个参数:InvocationHandler它是一个接口,它的做用是是代理实例的调用处理程序实现的接口,接口中定义了一个方法
目标Target
代理工厂
CGLIB动态代理
CGLIB(Code Generation Library)是一个开源项目
是一个强大的,高性能,高质量的Code生成类库,它能够在运行期扩展Java类与实现Java接口。CGLIB包的底层是经过使用一个小而快的字节码处理框架ASM,来转换字节码并生成新的类
若是你要单独使用CGLIB,那么须要导入cglib的jar包还须要一个asm相关jar包,可是spring框架的spring-core.jar包中已经集成了cglib与asm
注意:jdk的动态代理只能够为接口去完成操做,而cglib它能够为没有实现接口的类去作代理,也能够为实现接口的类去作代理。
Cglib动态代理
setCallback传递的参数是Callback类型,咱们使用的是MethodInterceptor
注意:cglib它能够为没有实现接口的类作代理,也能够为接口类作代理.
问题:spring采用的是哪种动态机制:
若是目标对象,有接口,优先使用jdk动态代理
若是目标对象,无接口,使用cglib动态代理。
Spring AOP编程
Spring的传统aop编程
讲解的目的是为了更好的理解aop。
在传统的spring aop开发中它支持加强(advice)有五种:
1. 前置通知 目标方法执行前加强 org.springframework.aop.MethodBeforeAdvice
2. 后置通知 目标方法执行后加强 org.springframework.aop.AfterReturningAdvice
3. 环绕通知 目标方法执行先后进行加强 org.aopalliance.intercept.MethodInterceptor
4. 异常抛出通知目标方法抛出异常后的加强org.springframework.aop.ThrowsAdvice
5. 引介通知在目标类中添加一些新的方法或属性(不讲解)
org.springframework.aop.IntroductionInterceptor
经典的基于代理的AOP开发(了解)
基本的jar包
1. bean
2. core
3. context
4. expression
5. aop
6. 须要aop联盟的依赖jar包
第一步:编写目标(target)
第二步加强(advice)
第三步在applicationContext.xml文件中配置
第四测试
基于aspectJ切点传统开发
第一步:在spring的配置文件中定义目标与通知
第二步:使用<aop:xxx>标签来完成切面与切点声明
注意1:须要在xml配置文件中导入aop声明
注意2:由于咱们使用aspectj的切面声明方式须要在导入aspectj的jar包
传统spring aop开发总结
第一步:编写目标对象(target)
第二步:编写通知(advice)
传统的aop开发中,通知是须要实现指定接口。
第三步在配置文件中配置切面(切面=切点+通知)
<aop:config>来声明要对aop进行配置
<aop:pointcut>它是用于声明切点(简单说就是对哪些方法进行拦截)
<aop:advisor> 定义传统的aop的切面,传统的aop切面它只能包含一个切点与一个加强
<aop:aspect>定义aspectj框架的切面.,它能够包含多个切点与多个通知
关于切点表达式写法
这个语法源于aspectJ的语法,spring中aop开发,对aspectj不是彻底支持,只支持部分语法。
在开发中使用的比较多的是execution语法.
关于execution语法经常使用:
1. execution(public * *()) 全部的public的方法
2. execution(*cn.itheima.aop.*(..)) 全部的aop包下的全部类的方法(不包含子包)
3. execution(*cn.itheima.aop..*(..)) 全部的aop包及其子包下的全部类的方法
4. execution(*cn.itheima.aop.IOrderService.*(..)) IOrderService接口中定义的全部方法
5. execution(*cn.itheima.aop.IOrderService+.*(..)) 匹配实现特定接口全部类的方法
6. execution(* save*(..)) 区配全部的以save开头的方法
Spring整合aspectj框架实现的aop
在如今的开发中使用这种方案比较多.
在spring2.0之后它支持jdk1.5注解,而整合aspectj后可使用aspectj语法,能够简化开发。
Aspect:切面 =切点+通知(多个切点与多个通知的组合)
AspectJ 它是一个第三方框架,spring从2.0后可使用aspectJ框架的部分语法.
AspectJ框架它定义的通知类型有6种
1. 前置通知Before 至关于BeforeAdvice
2. 后置通知AfterReturning 至关于AfterReturningAdvice
3. 环绕通知 Around 至关于MethodInterceptor
4. 抛出通知AfterThrowing 至关于ThrowAdvice
5. 引介通知DeclareParents 至关于IntroductionInterceptor
6. 最终通知After 无论是否异常,该通知都会执行
相比spring 的传统AOP Advice多了一个最终通知
基于xml配置方案
第一步:建立目标(target)
第二步:建立通知(加强 advice)
注意:在aspectj中它的加强能够不实现任何接口,只须要定义出加强功能(方法)
第三步:在spring的xml 配置文件中来配置
<aop:config>下的<aop:aspect>是aspectJ框架用来声明切面的。
前置通知
后置通知
环绕通知
异常抛出
注意:目标行为只有抛出了异常后才会执行这个加强方法
最终通知
不管是否有异常,最终通知都会执行.
关于通知上的参数
1. 在前置通知上能够添加JoinPoint参数
经过它能够获取目标相关的信息
使用前置通知能够完成日志记录,权限控制
2. 在后置通知上添加的参数
第二个参数val它能够获取目标方法的返回值
注意:须要在配置文件中配置
3. 环绕通知上的参数
它是咱们开发中应用最多的,能够完成日志操做,权限操做,性能监控,事务管理
4. 抛出异常通知上的参数
第二个参数Throwable它是用于接收抛出的异常
注意:须要在配置文件中声明
5. 最终通知上的参数
可使用最终通知完成资源释放
关于代理方式选择
在spring的aop开发中,它使用的是代理方案,代理实现有两种:
1. jdk的proxy
2. cglib
spring框架默认状况下,会对有接口的类使用proxy代理。没有接口的类使用cglib代理
Proxy-target-class的值默认是false,它表明有接口使用proxy代理
问题:若是如今对目标要使用cglib代理(不考虑是否有接口)?
只须要将proxy-target-class设置为true.
基于annotation方案
第一步:编写目标
在spring的配置文件中配置扫描注解
第二步:编写加强(advice)
使用@Aspect来声明切面
使用@Before来声明前置通知
注意:必须在spring的配置文件中开启aspectJ注解自动代理功能。
第三步:测试
其它通知类型及参数
后置通知
环绕通知
异常抛出通知
最终通知
使用@Pointcut注解定义切点
在每个通知中定义切点,工做量大,不方便维护,咱们可使用@Pointcut来声明切点
切点容许逻辑运算例如mypointcut()||mypointcut1
关于代理方式选择
Proxy-target-class默认值是false,表明的是若是目标是有接口的使用proxy代理,若是没有接口使用cglib.
若是将proxy-target-class=true,无论目标是否有接口,都会使用cglib进行代理。
Spring jdbc Template
Spring提供了一个jdbc模板,它相似于dbutils工具。
问题:如何使用spring jdbc template?
第一:要导入相关的jar包
在这个基础上咱们还须要导入
还须要导入相关的数据库驱动jar包。
第二:spring jdbc template快速入门
快速入门
第一步:导入相关jar包,建立了一个JdbcTemplateTest1测试类
第二步:建立库与表
CREATEDATABASE springtest;
USEspringtest;
CREATETABLE t_user(
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(20),
age INT,
sex VARCHAR(20)
)
INSERTINTO t_user VALUES(NULL,'tom',20,'男');
INSERTINTO t_user VALUES(NULL,'fox',30,'男');
INSERTINTO t_user VALUES(NULL,'tony',40,'男');
SELECT *FROM t_user;
第三步:编码
配置spring内置的链接池DriverManagerDataSource
C3P0开源链接池配置
1. 导入c3p0相关的jar包
2. 建立一个ComboPoolDataSource对象,设置相关的属性
引入外部属性文件
Spring支持将常常修改属性,在properties文件中声明,在xml配置文件中引入外部的properties文件的信息。
在applicationContext.xml文件中引入
在本身配置中须要从properties文件中引入的信息可使用${name}方式来获取
JdbcTemplate CRUD
执行insert update delete操做
只须要使用JdbcTemplate的update方法就能够执行insert update delete操做
执行select操做
简单数据返回
复杂数据返回
注意:若是只返回一个domain对象,可使用queryForObject方法,若是返回的是List<?>对象,可使用query方法,可是都须要使用RowMapper来对ResultSet进行处理。
RowMapper它有一个实现类叫BeanPropertyRowMapper
若是使用BeanPropertyRowmapper,实体类必须提供一个无参数的public构造方法,类中的bean属性名称与表中的列要对应
注意:这个类是在spring2.5后提供。
Spring 事务管理
案例—转帐操做
建立一个关于账户表
CREATETABLE account(
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(20),
money DOUBLE
)
INSERTINTO account VALUES(NULL,'tom',1000);
INSERTINTO account VALUES(NULL,'fox',1000);
建立service与dao
对于数据的操做使用spring jdbc template
关于service与dao的配置
咱们让dao去extends JdbcDaoSupport类,这个类中它建立了JdbcTempate,前提是咱们须要注入一个dataSource.
在dao中在获取JdbcTemplate可使用父类提供的getJdbcTemplate方法来获取。
转帐操做的问题
若是在转帐操做过程当中出现问题,那么转帐会出现问题,结果以下
也就是咱们程序须要事务控制。
Spring事务管理机制
Spring事务管理的四个优势:
1. 提供一致的对于不一样的事务管理的API
2. 支持声明式事务管理(重点)
3. 编程事务管理(在开发中应用比较少)
4. 优秀的整合与Spring的数据访问
咱们重点讲解spring的事务管理的相关的API,还有声明式事务管理
Spring事务管理主要提供了三个接口来完成
1. org.springframework.transaction.PlatformTransactionManager
这是一个事务管理器,能够来选择相关的平台(jdbc hibernate jpa…)
2. TransactionDefinition
它定义事务的一些相关信息 例如 隔离 传播 超时只读
3. TransactionStatus
它主要描述事务具体的运行状态
PlatformTransactionManager
平台事务管理器
在不一样的持久化层解决技术它的事务代码不同。
JDBC开发
Connection con=……;
con.setAutoCommit(false);//开启事务
con.rollback();
con.commit();
Hibernate开发
Session session=….;
Transactiont=session.beginTransaction();
t.commit();
t.rollback();
PlatformTransactionManager接口API
DataSourceTransactionManager 主要针对于JdbcTemplate开发 MyBatis开发
HibernateTransactionManasger主要针对于Hibernate开发
JpaTransactionManager 主要针对于JPA开发。
TransactionDefinition
它描述的是事务的定义信息。
在TransactionDefinition中定义了大量的常量
隔离
如下是关于隔离性相关信息
事务的四个特性 ACID 原子性 一致性 隔离性 持久性。
不考虑事务隔离性有什么问题?
脏读,不可重复读 虚读。
ISOLATION_DEFUALT 它使用后端数据库的默认隔离级别(spring中选项)
ISOLATION_READ_UNCOMMITTED 不能解决问题,会发生脏读 不可重复读 虚读
ISOLATION_READ_COMMITTED 能够解决脏读 会产生不可重复读与虚读。
ISOLATION_REPEATABLE_READ能够解决脏读,不可重复读解决不了虚读
ISOLATION_SERIALIZABLE串行化,能够解决全部问题
对于不现的数据库,它的底层默认事务隔离级别不同。
Oracle数据库它默认的是read_committed
Mysql数据库它默认的是repeatable_read.
超时
默认值是-1 它使用的是数据库默认的超时时间。
只读
它的值有两个true/false,若是选择true通常是在select操做时
传播
它解决的是两个被事务管理的方法互相调用问题。它与数据库不要紧,是程序内部维护的问题。
如下定义了事务的传播行为
以上操做中最经常使用的三种:
PROPAGATION_REQUIRED 默认值 两个操做处于同一个事务,若是以前没有事务,新建一个事务
两个操做处于不一样的事务
PROPAGATION_NESTED 它是一种嵌套事务,它是使用SavePoint来实现的。事务回滚时能够回滚到指定的savepoint,注意:它只对DataSourceTransactionManager有做用
如下了解
PROPAGATION_SUPPORTS 支持当前事务,若是不存在,就不使用事务
PROPAGATION_MANDATORY 支持当前事务,若是不存在,抛出异常
PROPAGATION_NOT_SUPPORTED 以非事务运行,若是有事务存在,挂起当前事务
PROPAGATION_NEVER 以非事务运行,若是有事务存在,抛出异常
TransactionStatus
它定义了事务状态信息,在事务运行过程当中,获得某个时间点的状态
声明式事务管理
事务管理方式
1. 编码方案不建议使用,它具备侵入性。在原有的业务代码基础上去添加事务管理代码
2. 声明式事务控制,基于AOP对目标进行代理,添加around环绕通知。
这种方案,它不具备侵入性,不须要修改原来的业务代码
基于xml配置声明式事务管理方案
第一步:在applicationContext.xml文件中添加aop与tx的名称空间
第二步:在applicationContext.xml文件中配置
Spring提供的advice是传统的springadvice
1. 声明事务管理器
2. 配置通知
Spring为咱们提供了一个TransactionInterceptor来完成加强
对于这个加强,咱们可使用spring为咱们提供的一个标签<tx:advice>来完成操做
3. 配置切面
由于使用的是传统的spring的advice,须要使用<aop:advisor>
基于annotation声明式事务管理方案
可使用@Transaction来在类或方法上添加声明式事务管理
注意:须要在applicationContext.xml文件中使用
至关于开启注解事务控制
问题:关于xml方式与annotation方式的优缺点?
从简单上来讲,使用注解更方便。
使用配置的方案,能够对事务配置进行集中维护。
SSH框架整合
SSh=struts2+spring+hibernate
struts2 2.3.24
spring 4.2.4
hibernate 5.0.7
关于xml配置文件的整合方式
SSH整合jar包
Struts2框架须要jar包
Asm 是关于字节码操做
Commons-fileupload 关于文件上传
Commons-io 关于io流操做工具
Commons-lang 也是一个工具,包含了关于数据与字符串操做
Freemaker 标签库模板文件
Javassist 它也是关于字节码操做,动态代理可使用它实现(相似于cglib)
Log4j关于日志
Ognl 关于ognl表达式
Struts2-core xwork-cor struts2框架底层是使用xwork
Struts2与spring整合还须要这个包
若是须要使用struts2提供的json处理
注意:若是使用注解方案,咱们还须要导入一个jar包
Hibernate框架须要的jar包
Antlr 语法解析包
Dom4j 解析xml
Geronimo-jta apache geronimo它是一个开源javaEE服务器 Geronimo-jta是这个开源项目提供jar包,在hibernate中是关于jta事务相关
Hibernate-commoins-annotations
这个包是咱们在hibernate下来使用jpa相关的注解,这样它不依赖于hibernate
Hibernate-core 开发hibernate必须
Hibernate-jpa 它是关于hibernate对jpa的支持
Jandex 用于索引annotation
Javassist 关于字节码操做(注意:strtus2中也引入这个jar包了)
Jboss-logging 它是关于jboss统一日志处理
若是使用关于jpa相关操做须要导入jpa依赖jar包
C3p0链接池
还须要数据库相关的驱动jar包
还须要静态日志处理
Spring框架须要的jar包
Spring最基本jar包
AOP开发
Spring jdbc
Spring 事务管理须要tx
Spring整合hibernate
Spring整合web开发
若是使用到junit测试
还须要commons-loggin jar包
建立工程完成整合前期准备
须要的配置文件:
Strtsu2框架 src/strtus.xml
Hibernate框架 src/hibernate.cfg.xml 在domain有 Xxx.hbm.xml
Spring框架 src/applicationContext.xml
关于日志 log4j.properties
关于数据库链接 db.properties
Spring整合hibernate
基本原理:就是由spring来管理hibernate的SessionFactory
方式一:零障碍整合(了解)
咱们只须要使用spring中提供的一个LocalSessionFacotry来加载Hibernate的配置文件。
Ssh-xml工程加载到服务器后,若是能够自动建立表,就表明spring整合hibernate ok.
注意:咱们必须配置spring的ContextLoaderListener
方式二(spring管理hibernate配置)
不在须要hibernate.cfg.xml文件,全部关于hibernate.cfg.xml文件中的配置都在spring的配置文件中来配置。
首先要配置数据源
接下来引入properties文件
建立LocalSessionFactoryBean来完成spring管理hibernate中的SessionFactory
上述的props能够简化成下面方案
加载hbm.xml配置文件
mappingResources它相似于咱们以前<mappingresource=””>
mappingLocations它加载时是根据类路径加载classpath:路径
mappingJarLocations它会加载jar文件中的hbm.xml文件
mappingDirectoryLocations 它加载的目录
spring整合hibernate后的DAO
spring整合hiberante后,咱们的dao只须要继承HibernateDaoSupport类
在HibernateDaoSupport中只须要注入SessionFactory就能够得到到HibernateTemplate,它是对hibernate操做的一个简单封装,可让咱们方便使用原来hibernate的操做.
编写service及测试
测试
事务管理
HibernateTemplate API介绍
保存操做 session.save()
修改操做 session.update()
删除操做 session.delete()
相似于session.saveOrUpdate()根据持久化对象的状态来判断执行save或update
获取操做 get() load()
Find操做 相似于session.createQuery().setParameter().list()
相似于hibernate中的QBC查询,彻底的面向对象方案
下面这个能够执行命名查询
能够在User.hbm.xml文件中定义hql或sql
Spring整合struts2框架
前期准备
建立一个addUser.jsp页面
建立UserAction类
Struts.xml文件中配置
Spring整合struts2原理分析
1. spring整合struts2框架必须导入一个jar包
struts2-spring-plugin.jar
2. struts2框架配置文件加载顺序
a. default.properties
b. struts-default.xml
c. strtus-plugin.xml
3. 在struts2框架中全部的action interceptor result全是bean,在struts2框架中默认是使用strtus2本身bean初化操做.
4. 当咱们在工程中导入struts2-spring-plugin.jar文件
就会加载这个包下的strtus-plugin.xml
这时bean的建立由spring来管理。
5. 这时在建立Action时它执行的代码
上述代码,在执行时,首先会从spring容器中来获取,若是获取不到,会buildBean
经过上述分析,spring整合struts2框架它的方式有两种
1. spring管理action(简单说就是在applicationContext.xml文件中来声明action)
2. action自动装配service
spring整合struts2框架方式一(掌握)
这种方案是基于spring管理action
1. 在applicationContext.xml文件中配置
2. 在action类中
3. 在struts.xml文件
Class的值就是bean的id值
注意:必须在web.xml文件中配置struts2框架的Filter
Spring整合struts2框架方式二(action中自动注入service)
Struts.xml文件中
Class仍是类的全名
这时就会将action类中须要的注入servcie自动注入
在default.properties中有一段配置
这时就会根据名称进行autoWires
咱们能够修改注入的方式
咱们在struts.xml文件中修改了注入的方式,根据type进行注入
Spring整合struts2框架总结
1. 若是在struts.xml文件中<action class=”cn.itheima.action.UserAction”>若是写的是全类名,咱们使用action自动装配service方案
2. 若是在struts.xml文件中<action class=”userAction”>这时,在applicationContext.xml文件中要配置<beanid=”userAction” class=” cn.itheima.action.UserAction”>
3. 以上操做的前提是必须导入struts2-spring-plugin.xml文件
在这个文件中它改变struts2的bean工厂
4. 默认状况下若是采用action自动装配service方案,这时每一次请求都会新建立一个action,而且service的装配类型是by name
5. 若是咱们采用的是spring管理action这种方案咱们必须在<bean>声明中添加scope=prototype”,缘由是struts2框架的action每一次请求都应该是一个新的action
关于annotation整合方式
Jar包导入
在原来的xml基础上在多导入一个jar包
只有导入这个jar包后,咱们才能使用struts2框架的注解 @Namespace @Action
配置文件
Web.xml文件中要配置
Spring的配置文件applicationContext.xml
Struts2的配置文件 struts.xml
使用JPA注解来定义PO类
@Entity 定义实体类
@Table 定义表
@Id 主键
@GeneratedValue 生成主键策略
@Column 定义列
Spring整合hibernate
Dao编写
如何在dao中获得HibernateTemplate对象,原来是在applicationContext.xml文件中经过配置方案注入了一个SessionFactory对象,UserDao的父类HibernateDaoSupport,会帮助咱们根据SessionFactory来获得HibernateTemplate
Service编写
问题:service须要事务管理,怎样处理?
Action编写
使用@Controller @Scope
以上注解的做用是由spring管理action,它是一个多例的。
问题:如何完成struts2框架的流程?
基于annotation的ssh整合总结
在ssh的annotation整合时,必需要多导入的一个包
对于dao,service,action咱们使用
@Repository @Service @Controller来完成bean注册。
在dao中咱们使用如下方案将SessionFactory注入,在dao中就可使用HibernateTemplate
在service及action中使用@Autowire来注入dao及service
必定要在applicationContext.xml文件中开启注解扫描
对于PO类咱们使用JPA的注解 @Entiry @Table @Id @GeneratedValue @Column
要在applicationContext.xml文件中配置SessionFactory时来肯定扫描包
对于Struts2框架,咱们须要@Namespace @Action @ParentPakcage @Result来定义struts2流程
要求action类必须是在action actions struts struts2这样的包中才会扫描struts2相关注解
SSH整合延迟加载问题解决
1. 修改UserDao中的findById
2. 添加一个user.jsp页面
3. 在UserAction中处理user_findById请求
以上程序在执行后,报错
解决no session问题:
1. 不使用延迟加载
2. 手动将延迟加载初始化 Hibernate.initialize(延迟对象)
3. 使用spring提供的一个OpenSessionInViewFilter来解决
基本的原理就是将session的关闭操做不在service层完成,而是在web层才关闭session.
注意:openSessionInViewFilter必定要在Struts2 Filter前配置.