Spring& H2 ^9 S0 F& c: o
- 是什么?4 q3 w# R* M% A% m( Q
$ q! H3 U; O( y& M4 y2 P- ^
Spring是基于JEE的轻量级的应用框架 % `. S+ Y1 S/ G8 {* t
- 有什么?
8 e. N: V0 |4 @; B. f2 o, W4 ^! r8 H" s! p- {0 l
! [; c$ v2 P7 g9 h
每个包的功能: Spring MVC:spring 本身提供的web 框架 WEB:集成其他的web 应用的框架,或者说是对其他web应用框架的支持。如struts,webwork JEE :集成一系列的jee的技术(对JEE技术的支持) DAO:封装了JDBC;(对JDBC的支持) ORM:提供了对ORM工具的集成(支持) AOP :面向切面编成 CORE:spring的核心包,提供bean的工厂和IOC容器 0 `4 b* t t! o# t$ c
- 能干什么?
( t/ y8 S7 v4 X$ ]3 W) v$ A5 n
# ?% {4 e3 q, W9 ^) y# ~ v: p
把一系列的jee的技术有效的组合在一起形成以良好的系统 ; f% r* J4 s! s1 K2 Q1 {; X
- 怎么用?
5 {2 g8 p3 v, o
5 Z4 H! X J5 b- 搭建web工程,引入spring的jar包
$ z8 u- z2 ~8 F: }9 w9 @( K W - 在web.xml中添加如下配置4 v) d' m7 T" x+ S' K; Y/ [
4 i5 ~0 u' Z+ C" Y2 l 3 r( V% J5 c1 |9 Q! O
: d/ e: O- G. ^; }) j8 c% a
contextConfigLocation3 ], v: k* f! |3 _( U5 a
classpath*:applicationContext*.xml
$ M4 [# O1 X6 T5 {7 i, c
" F( V) n& Z D 9 I4 `1 N& _/ }4 e( j4 G
struts2
7 I$ y7 ^# `1 {( i0 K" m 7 P8 e- K. R- T- y
org.apache.struts2.dispatcher.FilterDispatcher. s: n4 O4 ~" G0 Z, C$ Q$ p# G
3 E* y3 u+ w) @8 p 0 `1 Z! z: v$ n6 f' e
' P( W, K. Z" U3 \( g struts22 I; I9 @0 K0 x6 M
/*% g. {7 k; D& `- K$ `
. @ g# j) [4 [2 `3 L. A: R' E# K
0 @- d& u7 x4 g( i8 A5 P( M
( g0 g2 r0 U: f, ?% c: C
org.springframework.web.context.ContextLoaderListener) |7 C! Z2 K' G* N! e9 r7 v
4 e5 l+ U; z( ]% F. b
- 部署" O4 s7 X( y- B9 q: Z9 w1 E: d
' f( i, } U' F9 W$ J! c# a! x; q
$ v4 y0 z- P, o+ z
$ p, o7 G; Y0 P; @! o! ?$ {
& c! O: r& g! @ J$ D- 容器和bean
2 _! o) V' o \, m* n9 I
Bean :是指受spring的ioc管理的对象称为bean 容器 :(与jee的容器类比) Jee :提供组件的运行环境和管理组件的生命周期(不能单独存在) Spring :提供bean的运行环境和管理bean的生命周期(可以单独存在) 8 v0 C6 z4 x6 v
9 z* x* r8 o) U$ Y4 _- DI依赖注入
1 d+ @* K8 g- I e0 Y3 Y, U: f
1. 应用程序依赖spring注入所需要的对象 IOC和DI是对同一种事情的不同描述 2.setter注入: 在配置文件中将接口的实现配置为bean在应用程序中注入bean 例如: 在配置文件中 $ o8 w8 k2 P3 U/ A) Z X0 ?/ O" Y0 _& h
/ u/ H& Y2 Z& }. W8 ?9 n
4 Z3 o+ V% D/ K4 w4 _! y; T; h
在应用程序中 Public DBDAO dao ; Public void setDao(DBDAO dao){ This.dao = dao; } 3.构造器注入
- {# ]) v# l" J3 d. o2 t! G$ u& }4.ref 表示参照其它的bean 在参照的过程中一定要注意死循环 5.自动装配———–〉no 自动装配根据名字来匹配相应的bean 尽量不要去自动装配 6.lookup注入 7.singleton 1.单例模式是整个的jvm中只有一个实例 2.spring的singleton是指在spring的容器中只有一个实例 一个生命周期中只有一个实例 8.DI的优点: 1.程序被动等待,强化面向接口编成 2.切断了对象或组件之间的联系,使程序的结构更加松散,运行和维护更加简单
( s4 L" ~7 ]6 R) y$ h- Aop面向切面编程
* X+ _/ U% L8 Q* R$ e, U
* }3 j: c5 b+ h# ~4 M/ J R* I. ~
1.AOP面向切面编程 一些较好的模式或者是示例—-范式. r& N8 u) r3 D; j; ], }4 @& a
切面:一个切面代表我们所关注的一系列的共同的功能点(模块之间的共同的功能点) 2.AOP的思想: 主动—->被动(追加功能)/ _' \5 `" z9 T1 P+ l6 w
3.AOP 的概念9 [9 L- R) R) h& N1 O
1.切面 :我们所关注的功能点 2.连接点 :事件的触发点(方法的执行) 3.通知 :连接点触发时执行的动作(方法) 4.切入点 :一系列的连接点的集合 (连接点的模块化) 5.引入 :扩展的功能 6.目标对象 :包含连接点的对象 7.aop代理 :实现机制 8.织入 :把advice和目标对象连接起来 4.AOP的事件机制
0 M. {, M" V% f$ O: F8 Z 1.通过切面找出一系列共同的功能点 2.找到目标对象(在标准的spring 中 接口的实现类为target) 3.找到切入点 4.确定连接点 5.通知spring AOP,查询xml文件,通过代理找到advice。 6.由aop代理来实现动态织入 7 n4 N# Q' U2 O! e2 r7 K
6 k+ M& r, z: @8 s5 @ j' l
5 P$ d+ h/ S! w
$ `4 \9 Y1 L. I1 g$ v
* @" X' t3 }* Q) p0 P- q$ O9 F% h
, l9 y; k; \" s5 h& G% N' w
# H. D' \0 o% A+ v3 E" W5. AspectJ
n1 O+ `( `: O4 F) d p* ^ 5.1.在xml中配置比较烦琐( y7 P0 W; f5 `2 b
所有的入口必须从一个代理(ProxyFactoryBean)开始
9 ]+ n4 {3 L9 \8 B 1 K$ i: e9 Y5 m0 b4 l+ ]
, }$ Z* T2 P1 n7 _
! G) |: J: Y6 A% z9 P$ X
g/ d Z( x" b. F4 j$ G; i$ J
/ J! }" t3 ^ f# M8 l- ^8 A
$ W5 `& ^! d6 Z c& g5 @3 B 2 s) g7 W1 ?7 m0 k, _& M
: B, Y* V, E; Y4 {9 ?
expression=“execution(* com.javakc.aop.MyTarget.t*())”/>
. h% x8 v9 c' F" P3 v : b; p% m, G3 g9 U; ~" O" ~: N
, ^6 ]' v, E2 M c7 U
, V+ w' E# s3 q
* D2 i2 a2 x2 A- I% n- r. L# f4 X' Y
- r) r2 c. W/ o( q5 g. n& E5.3.使用注解的方法相对简单: E! p! h/ l6 ` [ D- x# L5 S
@AspectJ的基本语法( G8 Z! ^- {* c1 G+ E! q% N9 r
1.@Aspect声明一个切面,将一系列的共同的功能定义成一个切面: W0 c7 t7 Q5 _. h
直接在类上定义@Aspect7 {% R ~) u- _, i
2.@Pointcut声明切入点
2 A; V$ Q ~$ u/ N! \ 2.1、用一个专门的类来定义pointcut,类中的方法名就是该pointcut的名字
, l* c; K% {( |" R/ `" h: K! c 2.2、可以使用匿名的pointcut
, b1 s# ~5 S% a* t1 b0 k ^ 2.3、执行切点的几种方法8 R. `1 m& [! o9 O
2.3.1 execute(public * 包结构.*.*.(..)) 可以指定到具体的方法
3 k7 M, W5 n+ O; Z 2.3.2 within 指定到包,不能指定到类
: n% d( u3 g" K y! \9 H( L& ~( G( m5 I within(”com.javakc.spring..*”)6 L! K/ Y! b% |2 p2 C
2.3.3 this 指定到实现接口的所有的实现类
0 Z% ~: n+ l! R# W* E! A M4 p 2.3.4 target 指定具体的实现类
@2 |: a4 M* {0 Z 5.4.advice的五种类型的示例
/ {, P! N. \* J+ p3 J 客户端必须从接口走才能得到监控,实现想要追加的功能' D1 w9 s0 Y* L5 C7 V( p
5.4.1.@AfterReturning(pointcut=”” returning=”retVal”)
! r( k: x% }; h1 | 追加的方法的参数名字一定要与retrning的名字相同
) ]- _1 M. G8 r. {9 A( X, z: F 在注解@AfterReturning中必须加上pointcut和returning两个参数- Y, r8 r% h: a& Y: Q }/ H
pointcut指所要监控的目标对象的方法
0 x7 m4 M! O, N s D3 ] 得到目标对象的方法的返回值,来作为参数,进行下一步的处理,参数没有顺序,按参数的名字进行匹配; V; }& C; M) a5 t5 O# t
完成追加的功能
3 {( [( i# b0 ?! i9 J 1 定义一个pointcut,通过方法名来作为pointcut的名称来引用0 d; n3 m3 l$ M( b, U" j- ]6 I9 O
(1).@AfterReturning(“com.javakc.spring.schemaaop.TestPointcut.t4()”)
& B1 V( P/ T1 v' L/ ^9 Z (2).
3 f) H& w9 J$ M1 {9 d+ V 2.直接引用匿名的pointcut
0 t j9 \) P h+ g) m: |' Q (1).@AfterReturning(“execution(4 }& F& k4 t. f" J" i
* com.javakc.spring.schemaaop.Api.test4())”)7 O p5 |. H% r# \! K5 R
(2).@AfterReturning(pointcut=
) I. {# d) s9 P; V4 H, A$ \8 D “com.javakc.spring.schemaaop.TestPointcut.t4() &&
6 Y4 l* J. P; H9 ~ J6 a args(str)”, returning=”retVal”)/ B! j7 O4 ]. F+ Q0 S j
@AfterReturning (pointcut=”com.javakc.spring.schemaaop.TestPointcut.t4() && args(str)”,returning=”retVal”)+ U4 `& J$ N; k/ ^* S8 k8 V
public void testAfterReturning(String str,Object retVal){
8 V2 r2 `' V( \, Y! _ System.out.println(“afterReturning1=>”+retVal+”=>”+str);/ V. A+ ~* J. w# b9 W2 R
}
8 }( k0 v4 P- N6 Z% T4 j( ?3 q) W 5.4.2.@Aronud! k3 K& y2 _3 I
注解@Around环绕追加功能;# X' k; S( t/ U3 V( a
在执行目标对象的方法的前、后追加功能;7 h: b8 R! { T- ^2 w# J
必须有参数;第一个参数的类型必须为ProceedingJoinPoint;9 n: ]! U9 N6 H/ W( Y
通过ProceedingJoinPoint的实例的proceed来调用所监控的
a7 J; }) [7 u$ P Q* } H0 P 目标对象的方法
: ~+ d0 {% a! c 1 定义一个pointcut,通过方法名来作为pointcut的名称来引用0 t M- ~: c0 g# c4 g9 o; E
(1).@Around(“com.javakc.spring.schemaaop.TestPointcut.t1()”)# I& K% }) f* s' ^9 c0 o
(2).@Around(“com.javakc.spring.schemaaop.TestPointcut.t2()3 R9 x: n& D0 k% U* _# {; K
&& args(str)”)2 ]2 M$ l- o4 F- `/ F+ c
2.直接引用匿名的pointcut6 Q! ~3 s+ D- v2 I
(1).@Around(“execution(" G3 s. o% W e( g M; q
* com.javakc.spring.schemaaop.Api.test1())”)
: c/ a( F2 s4 S! k (2).@Around(“execution(
9 P2 Z/ D/ Y* F; y+ h * com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)
, V, b3 x% q+ R4 Z* x3 h // @Around(“com.javakc.spring.schemaaop.TestPointcut.t2() && args(str)”)3 a6 a# g. ?2 U
@Around(“execution(* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)9 L) H: V/ q5 U6 P
public void testAround(ProceedingJoinPoint prj,String str) throws Throwable{
9 l4 s2 J4 u: V. c; n3 ]6 z System.out.println(“around1==========before1pointcut==>”+str). W: P) Y' {) H/ I- K/ \1 s
Object obj = prj.proceed();" w' l* \8 q) d, q. ~. A1 e
System.out.println(“around1==========after1pointcut==>”+str);
' X( r* {2 Q6 q }
3 v8 Q# u8 A/ a 5.4.3.@Before
# z8 ^, W4 `1 X4 l 注解@Before在执行目标对象的方法前追加相应的功能* ]8 R, p. I- t# B5 u6 T
1 定义一个pointcut,通过方法名来作为pointcut的名称来引用9 G: } A6 p; a' P
(1).@Before(“com.javakc.spring.schemaaop.TestPointcut.t1()”)9 r* @! Q h' ^$ ^1 q9 ]3 f$ }
(2).@Before(“com.javakc.spring.schemaaop.TestPointcut.t2() && args(str)”)
0 h6 ~; `4 g+ i% k 注意args后的名称与参数名相同; Y h4 s/ Z3 t
2.直接引用匿名的pointcut! R) Q8 x; F0 `
(1).@Before(“execution(* com.javakc.spring.schemaaop.Api.test1())”)
0 C7 H, w& e; N4 {' d# W5 i (2).@Before(“execution(* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)
2 w) j4 A+ P2 i' p+ x 注意args后的名称与参数名相同
6 H' A2 ], m9 g0 i& ` // @Before(“com.javakc.spring.schemaaop.TestPointcut.t2() && args(str)”)
- ^ h, M5 f: V$ J& ] @Before(“execution(* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)& u. Y' d7 t0 a- Q9 @
public void testBeforeParam(String str){$ U( ]9 g9 o4 \0 L, o+ r. g- x
System.out.println(“before1=param=>”+str);
7 D; p7 L/ _9 E; _, Q/ [ }7 W* [4 { M. e# N5 k
?% {/ Y. z0 ~5.4.4.@After
* x P, f& I! K2 h% V! u 注解@After在执行目标对象的方法后追加相应的功能4 u2 l0 E Q; ?0 u: G+ X
1 定义一个pointcut,通过方法名来作为pointcut的名称来引用8 \) S6 a* U: z; q b; K$ \
(1).@After(“com.javakc.spring.schemaaop.TestPointcut.t1()”)
3 r. _8 R, V& v; l, s8 F 2.直接引用匿名的pointcut
% Q1 o% H. |$ Y X. p: N (1).@After(“execution(* com.javakc.spring.schemaaop.Api.test1())”)
! M! {7 j6 G1 `, W' y# i @After(“com.javakc.spring.schemaaop.TestPointcut.t1()”)4 }$ F4 s+ r( J, c
public void testAfter(){3 Q! W/ Z$ o' a' ]* V# T- I* P" ?
System.out.println(“after1== >pointcut”);$ H0 V0 k2 y- p d
}
& u. N6 @1 Q ]. C 5.4.5.@AfterThorwing8 z7 s# F4 z9 E. i
) Q( r$ S$ ?, u# g8 b& V7 Y9 b
J2 L% m; w) e- m9 a- 描述一下spring中BeanFactory和ApplicationContext的差别7 ~& W, b& U: k% a9 j
8 m! i: t- i/ { p. {
BeanFactory是一个Interface,这是Spring的核心。它仅仅只是提供的一些基本功能。ApplicaionContext 也是一个interface,这是从BeanFactory继承过来的所以它具备了BeanFactory的所有功能。但它也从其它的类或interface得到了一些特性。比如提供国际化的消息访问,资源访问,事件传播。 但其主要区别在于BeanFactory是延迟加载,如果Bean的某一个属性没有注入,BeanFactory加载后,直至第一次使用getBean方法调用此Bean时才会抛出异常;而ApplicationContext则在初始化自身时检验,这样有利于检查所依赖属性是否注入;所以通常情况下我们选择使用ApplicationContext. 代码示例: BeanFactory beanFactory = new XmlBeanFactory(new FileSystemResource(“beans.xml”)); ApplicationContext cxt = new ClassPathXmlApplicationContext(“beans.xml”); 9 Z. @* }! H; s% x
- 谈谈spring对DAO的支持$ }0 u' {2 u6 i
+ ]! f F' i" G( a) }! X; B% G" B2 M }0 m
Spring提供的DAO(数据访问对象)支持主要的目的是便于以标准的方式使用不同的数据访问技术。
3 {: _! R& z0 V( i6 M& U. s 简化 DAO 组件的开发。
3 U. B8 l- q& E9 FSpring提供了一套抽象DAO类供你扩展。这些抽象类提供了一些方法,用来简化代码开发。/ K) x, c e$ p+ J& V/ p% h4 T1 a
IoC 容器的使用,提供了 DAO 组件与业务逻辑组件之间的解耦。所有的 DAO 组件,都由容器负责注入到业务逻辑组件中,其业务组件无须关心 DAO 组件的实现。0 Q+ o3 A5 Q" B2 E" S3 {- P
面向接口编程及 DAO 模式的使用,提高了系统组件之间的解耦,降低了系统重构的成本。8 L4 m4 m* P8 U9 _! v
方便的事务管理: Spring的声明式事务管理力度是方法级。8 N8 e* T& G3 ^, D+ {$ }0 K
异常包装:Spring能够包装Hibernate异常,把它们从CheckedException变为RuntimeException; 开发者可选择在恰当的层处理数据中不可恢复的异常,从而避免烦琐的 catch/throw 及异常声明。) n3 {! L- v4 y8 Y3 C5 y% P* n. x
: K) I5 K* t" I8 ?5 ]
% A3 t8 y0 X9 g- 谈谈spring对hibernate的支持3 u. M" ]. Y6 }' j4 W
" i: ^( R* I2 `3 X+ e
在所有的 ORM 框架中, Sping 对 Hibernate 的支持最好。如 SessionFactory 的注入、HibernateTemplate 的简化操作及 DAO 支持等。另外, Spring 还提供了统一的异常体系及声明式事务管理等。
) V4 e8 N- l7 d2 C 一旦 Hibernate 处于 Spring 的管理下, Hibernate 所需要的基础资源,都由 Spring 提供注入。Hibernate 创建 SessionFactory 必需的 DataSource ,执行持久化必需的 Session 及持久层访问必需的事务控制等,这些原本必须通过代码控制的逻辑,都将由Spring 接管ataSource, SessionFactory, TransactionManager等,都将作为 Spring 容器中的 bean。将这些bean 放在配置文件中管理。
! {8 E& |# H( Z% j 1、通用的资源管理: Spring 的 ApplicationContext 能管理 SessionFactory,使得配置值很容易被管理和修改,无须使用Hibernate 的配置文件。详细配置如下:" A: Q/ }$ h! g4 n8 g: ?2 h \
' [' j2 k, o5 h c0 C4 _$ B, g class=“org.apache.commons.dbcp.BasicDataSource”>6 o7 M8 H4 [, ^
: B+ O6 G0 P' O, _1 {4 I. B
oracle.jdbc.driver.OracleDriver1 z+ @* b7 _ B% E: ?& ^
+ r0 z$ c& F% |# `4 B
. p: E5 o2 f% L ] jdbcracle:thinlocalhost:1521rcl0 {2 [/ }$ b% J3 t8 f
" i1 I8 C- G/ ^8 F! n
, b/ ]4 U9 z: J+ Z- c1 h% D( w( R javakc2) a1 b7 r8 n0 V6 d4 m) a9 N8 l) J
* P5 |1 ^# \# P
q3 R: _5 z# j# ?6 Y/ o javakc2
8 I/ g3 N7 F; b$ f1 F
6 z" T4 q# f! \" i5 r P3 M U
b( K: D. P8 j( E ! s* k. }1 \! k, u$ F7 O$ \
class=“org.springframework.orm.hibernate3.LocalSessionFactoryBean”>% A. \8 R. d# F y: d
Y V% H( C$ `
2 h/ v! g% j" n6 t. T8 x7 q' S! U 6 A* u; s5 J& [7 Y( d7 R
com/javakc/spring/h3/UserModel.hbm.xml
. V, P. L5 I" X! x8 c
. P' s' Q8 _; B 2 G1 q+ M3 a b8 V( {$ d
7 n H; N- K; t; _
; P5 e- `6 W: N/ W0 K
hibernate.dialect=org.hibernate.dialect.OracleDialect! g0 O2 t6 K+ Z! Q
* x& B# U, w* u: D+ t1 j
* x% C! [2 D. R: j: b) j# @% G
/ z3 y- K( |. P- ^9 T7 l
# x! \# z) Z) s0 n) X o B) p3 r. ~% o1 k' ?
6 P8 Y" o. F1 k% L1 s; ?! m 如果需要使用容器管理的数据源,则无须提供数据驱动等信息,只需要提供数据源的JNDI 即可。对上文的SessionFactory只需将dataSource的配置替换成 JNDI 数据源,并将原有的 myDataSource Bean 替换成如下所示: class=“org.springframework.jndi.JndiObjectFactoryBean”>% B! f. |- ~/ C# X9 X! N' g
- g. W; r1 A8 Q java:comp/env/jdbc/myds
3 y5 b1 j* P8 y) N. x* Q$ X) N
5 B5 c5 ^' z( |; o 2、有效的 Session 管理: Dao类继承HibernateDaoSurport后,Spring 提供了 HibernateTemplate,用于持久层访问,该模板类无须显示打开 Session及关闭 Session。它只要获得 SessionFactory 的引用,将可以智能打开 Session,并在持久化访问结束后关闭 Session ,程序开发只需完成持久层逻辑,通用的操作则由HibernateTemplate 完成。 3、统一的事务管理。无论是编程式事务,还是声明式事务, Spring 都提供一致的编程模型,无须烦琐的开始事务、显式提交及回滚。 建议使用声明式事务管理,Spring 的声明式事务以 Spring 的 AOP 为基础。可将事务管理逻辑与代码分离。代码中无须实现任何事务逻辑,程序开发者可以更专注于业务逻辑的实现。声明式事务不与任何事务策略藕合,采用声明式事务可以方便地在全局事务和局部事务之间切换。 Spring声明性事务有两种配置方法,一种是xml配置: - s; v' `; E% [) H+ J! n* L. g
# k0 S9 _1 z6 \# T: W. b9 d+ F1 ^
4 ]2 i% ?# Y, ^& J3 V3 k
% s9 N% _: n5 I) J. m. P
$ v! k9 ?$ M( h+ I' L2 m
6 @. z, G6 j/ v; Q/ z! q 0 k! R0 q' }) b% d& j
: q" F" A, K( e Y
n4 m( y, [. L/ r! v0 r
" J9 W4 v6 f' H8 c1 }( ~
8 i2 q, m2 t+ A9 W- |1 s
% z5 h& q# [( f$ y8 ?' J8 h * V4 S4 o, ~3 w' M
! @- z( n9 h+ Q
另一种是通过注解,在需要添加事务的类上注明 @Transactional 8 s; {) i8 T. \' c
Spring2.0之前事务的写法
; G* i- I& D( ?+ Z5 e9 S) q- h5 P' }0 j2 b
* n7 s5 p, S9 K) z
class=”org.springframework.transaction.interceptor.TransactionProxyFactoryBean”
* \7 j# m8 A5 h9 U ]/ x: g2 ?% a1 T |+ r' ]- T5 z
abstract=”true”>
& ~7 U: B* C. s
6 Y [ ^& I8 d4 g! c1 E, a) k4 ~9 \- c
% S4 q9 X) V4 @/ \8 Q/ Q
# r w& f# N; c& E
PROPAGATION_REQUIRED,readOnly0 R2 m+ n& e! d- F( A
5 g0 V8 ~6 t2 n$ |( [ PROPAGATION_REQUIRED
& a0 r+ R1 f: P7 J0 R0 E4 V
* ]" \: J7 F+ v* @) F* z# n- G; \5 l) ]
# X$ D. O f! N! T
# C( Q2 H5 S" d( R/ n2 o
9 o$ h) J; [, ` |
& E* F" U5 X9 ~+ `9 l& o, e, h, X5 B( O) k1 d, x; d0 h
- 谈谈Spring对事务的支持9 e9 O5 [' b4 u- o/ S
4 h' G4 T) h+ a3 }
$ h2 ^; V) e, S; K1、声明式事务管理:
1.流程:由客户端访问—-aop监控—-调用advice来追加事务 2.做法: 2.1 在配置文件的头中引入xmlns:tx 和schema的文件 2.2 2.3 注入数据源
0 ~: |6 m) `/ m) L1 x( O* T
# Z7 j5 o d! b* b+ d- }) C8 D/ }: V; O# K2 x( q
: f4 f7 k. K6 l4 @+ j" P
# v5 j6 P" |% k% Y! _
$ |$ x J' W! _2.4 由spring实现的事务管理,但需要注入数据源
' u* s; B, `2 W4 w. Y2 ?- _( V! U5 p
* ~ v: v- c p4 r/ S r" i
2.5 事务监控所有的方法(事务加强)
. {% E4 m+ r2 N/ B4 d7 h8 S
& q9 N" b% i) R9 ?; C7 q9 \
' C# ~! X# S1 ^3 a0 \2 T- L6 y: N {* ^0 B& R
4 o# P) m2 F( q: G: `& P2.6 定义切入点
0 C0 |5 W9 [0 ~
: Y7 P( T6 h# }! v1 _
' B t- _8 K$ `7 B" A6 Z6 Y ?$ j- j+ W, A- P1 g
3 W! r% h: b8 y; I4 [* K3 A
2、使用注解实现事务管理: 1.注解@Transcational (可以在类上,也可以在方法上) 2.在配置文件中同样需要注入dataSource和spring的事务管理 3.使用注解的方法来追加事务 注解驱动
' K! Z7 M x8 X+ y
0 r4 B/ b) t9 `5 M0 Q3 P1 h如何在Spring中使用Hibernate的事务:
$ _( B2 b" C, \7 y+ ]/ G 5 X) z3 ?; A& |- `' C0 K
9 z3 m P" [, @. Y6 ]
x( ^6 {7 `! u6 A" A* d如何在Spring中使用JTA的事务:
7 x6 g0 e! P: \5 r% u. _' \' b 7 ~& K8 [) S# V+ H# D7 S* [4 Z
|