Spring
, y2 H4 D# v) b. V6 s- 是什么?5 \- v8 n# ]. V4 x3 C5 a% i
4 h$ K0 {2 S' b6 P3 V2 t2 k. N
Spring是基于JEE的轻量级的应用框架
4 o: q$ B, o# w, p5 |% @- 有什么?
2 C6 e' N5 g( y7 t. H3 z# x
5 n: ]% p) u: G/ o( n9 v: G b3 i$ S( ?# v$ @) F
每个包的功能: Spring MVC:spring 本身提供的web 框架 WEB:集成其他的web 应用的框架,或者说是对其他web应用框架的支持。如struts,webwork JEE :集成一系列的jee的技术(对JEE技术的支持) DAO:封装了JDBC;(对JDBC的支持) ORM:提供了对ORM工具的集成(支持) AOP :面向切面编成 CORE:spring的核心包,提供bean的工厂和IOC容器 ' x5 a1 S7 ?1 X3 u3 f, W
- 能干什么?
1 t! I0 I) a5 u! a, D2 {3 w: x; l9 A7 F- Y* v4 Z
把一系列的jee的技术有效的组合在一起形成以良好的系统
, N+ J3 h6 @/ _0 U8 Z6 X- 怎么用?7 c# C, v$ K+ O. Z( Q" v" P" k- d U
8 U! @6 Y" H3 [; Z& _- 搭建web工程,引入spring的jar包
. f5 f& D' \* e" k - 在web.xml中添加如下配置
; I6 O4 P% a" l% V! w: e6 G# H1 h2 }
0 N4 M# s2 k. C7 V x; r: ], ^( Y" d% ^
% q4 o' {% L* i% Q/ Y
contextConfigLocation0 d; V# Y+ z, Z5 h
classpath*:applicationContext*.xml
, k# m, C6 i J1 [( n6 Y! U ) x* D2 v. Q Q0 f: Z- L
6 _; D2 e4 r# l) _7 I1 B [& K struts2
1 s( Z7 y) l6 c) J8 `' g3 P 6 o5 I+ W0 y$ C, J& \6 D( ]
org.apache.struts2.dispatcher.FilterDispatcher
6 c5 ?3 i+ p' a% c0 Y : M8 Z: ?, n8 ^/ q9 S: F
F* \* X6 S8 V } B" U
4 y3 u0 A& H1 ^; k2 y6 _ struts2" w0 ]& k/ C+ D; Z3 ?, j8 F
/*4 J# }' `: `2 i8 t
5 n9 ]7 k, q, F' v$ G1 o5 R
2 c$ C0 y/ A& A+ K1 g
" v& Z4 v1 v. p' T+ j
org.springframework.web.context.ContextLoaderListener
4 L* j1 r9 p1 W& d. q 8 L* X# F" T/ d( n" z. F
- 部署
0 B+ y% u( T6 L; \/ ^9 u- s4 U* |# y0 p6 o; [: E
0 j" ^' P. o4 o
$ G; d, j9 f: R# k* F& A% u% `
7 D8 M1 z! J' l! Y# a$ Y- 容器和bean
L: E# b+ g7 ]5 x- L
Bean :是指受spring的ioc管理的对象称为bean 容器 :(与jee的容器类比) Jee :提供组件的运行环境和管理组件的生命周期(不能单独存在) Spring :提供bean的运行环境和管理bean的生命周期(可以单独存在)
1 i1 K2 F" ^, r7 M( y, t9 r/ \. H* R, m; \# m% g, d1 K( w @
1. 应用程序依赖spring注入所需要的对象 IOC和DI是对同一种事情的不同描述 2.setter注入: 在配置文件中将接口的实现配置为bean在应用程序中注入bean 例如: 在配置文件中
/ d/ b" @& w3 R6 ^% g9 H
0 M& Q& l- q0 v3 L& m+ g" E. ~: ]
3 |, O1 q0 j* I: [在应用程序中 Public DBDAO dao ; Public void setDao(DBDAO dao){ This.dao = dao; } 3.构造器注入
; N( s2 Q7 s) _1 C4.ref 表示参照其它的bean 在参照的过程中一定要注意死循环 5.自动装配———–〉no 自动装配根据名字来匹配相应的bean 尽量不要去自动装配 6.lookup注入 7.singleton 1.单例模式是整个的jvm中只有一个实例 2.spring的singleton是指在spring的容器中只有一个实例 一个生命周期中只有一个实例 8.DI的优点: 1.程序被动等待,强化面向接口编成 2.切断了对象或组件之间的联系,使程序的结构更加松散,运行和维护更加简单 ( |, ~( Y: {7 j6 ~
- Aop面向切面编程7 g- t7 _, U$ W" v/ w9 p
* E1 Q# F1 U' w% Z1 M1 `# j
1.AOP面向切面编程 一些较好的模式或者是示例—-范式; d. A% k! s+ s5 }: p/ _) a
切面:一个切面代表我们所关注的一系列的共同的功能点(模块之间的共同的功能点) 2.AOP的思想: 主动—->被动(追加功能)
% c* X; d5 H; E7 n6 L 3.AOP 的概念
( g$ {' T3 ]6 N8 ?# z 1.切面 :我们所关注的功能点 2.连接点 :事件的触发点(方法的执行) 3.通知 :连接点触发时执行的动作(方法) 4.切入点 :一系列的连接点的集合 (连接点的模块化) 5.引入 :扩展的功能 6.目标对象 :包含连接点的对象 7.aop代理 :实现机制 8.织入 :把advice和目标对象连接起来 4.AOP的事件机制
) R+ ^. P+ `, ~/ l 1.通过切面找出一系列共同的功能点 2.找到目标对象(在标准的spring 中 接口的实现类为target) 3.找到切入点 4.确定连接点 5.通知spring AOP,查询xml文件,通过代理找到advice。 6.由aop代理来实现动态织入
$ P3 i+ v& y- `, d
" s0 E& p% S$ s5 A M
( P, x" e# V2 y9 V$ b: |0 `
+ f$ g* N$ G. J) E% m. x* S; i
- ]2 A$ _# _5 t+ y0 @" K% s- ^% V. J1 t6 |# Q) M3 v
- z; l/ l3 Z, k4 w' f
5. AspectJ
+ @4 B+ H/ a @ 5.1.在xml中配置比较烦琐$ ^+ T7 Q( ], }
所有的入口必须从一个代理(ProxyFactoryBean)开始0 j$ o0 a2 A3 \
# j O1 W0 q5 Q4 _5 ]5 O% n# t+ u / w6 O! j6 w8 a9 D ^+ f1 q& @7 e
% |( E7 g* H( c+ }1 C# z4 X" @
* \9 n! u ~5 L' V8 G; `5 J: b$ [
( K+ a) E' B o( g3 V
- V8 F9 }/ Y9 V$ L! N+ @ . m8 y" X( Y! W, n2 ?) ^9 c% V
expression=“execution(* com.javakc.aop.MyTarget.t*())”/>
+ t) O& v' _# W+ D) [2 g, b2 M; J
5 n; m1 s5 n1 i3 w! G' _) y
' u) } U! O0 Z9 A0 ] + Z; y) n8 \- Y9 E5 u. W
0 t, [7 I' h& G( H0 I# u& P
) J s. Q$ h# |5.3.使用注解的方法相对简单
) [8 ?3 T* m2 o! d! j* j @AspectJ的基本语法
' y$ H, |8 n' n' c, z- o 1.@Aspect声明一个切面,将一系列的共同的功能定义成一个切面
M& @2 ~5 d& S- k 直接在类上定义@Aspect
/ P+ z0 B/ O* |/ f/ F4 ~$ P& C 2.@Pointcut声明切入点
Q, a7 [5 S l4 A+ T 2.1、用一个专门的类来定义pointcut,类中的方法名就是该pointcut的名字
& D+ x% L( U4 h 2.2、可以使用匿名的pointcut# ~# K& {( e# t, H6 S
2.3、执行切点的几种方法
% F0 E6 K: f# ^' n5 a( s 2.3.1 execute(public * 包结构.*.*.(..)) 可以指定到具体的方法3 r9 R* E3 c+ y! Y- ]1 t6 K
2.3.2 within 指定到包,不能指定到类
. s2 r+ t- a% R5 q/ y& T within(”com.javakc.spring..*”)/ r3 I0 c' R8 m* P' f
2.3.3 this 指定到实现接口的所有的实现类
9 G5 A% {. C, D! m6 D 2.3.4 target 指定具体的实现类
, ^& @5 }5 X6 N+ i; A6 ]3 z o 5.4.advice的五种类型的示例, Q; v: w0 S5 v' ^2 R5 D6 L
客户端必须从接口走才能得到监控,实现想要追加的功能
5 d5 [9 u+ J0 d, ?) F9 h 5.4.1.@AfterReturning(pointcut=”” returning=”retVal”)
9 l% d$ J2 A" |$ |8 G( Y. \ 追加的方法的参数名字一定要与retrning的名字相同
/ j j; Q ~. ?- N 在注解@AfterReturning中必须加上pointcut和returning两个参数
& _3 B6 { g/ T+ m/ N9 Y; } pointcut指所要监控的目标对象的方法 Y9 [" T& S. F* F
得到目标对象的方法的返回值,来作为参数,进行下一步的处理,参数没有顺序,按参数的名字进行匹配0 e1 W( [4 j% u I9 R
完成追加的功能0 W7 ^9 j0 J: v& {* |
1 定义一个pointcut,通过方法名来作为pointcut的名称来引用
: |. S' s) N5 X: s! w' e+ O1 E }/ x (1).@AfterReturning(“com.javakc.spring.schemaaop.TestPointcut.t4()”): b. b- z: q6 h. i. }! e
(2).1 C# ?8 P# r/ [! }( j( p* A9 v7 T
2.直接引用匿名的pointcut
' v8 ` s2 B* @ (1).@AfterReturning(“execution(
* D* T" J) p8 ?! \. C0 ~ * com.javakc.spring.schemaaop.Api.test4())”)
% C, S) [9 R5 q- a0 y (2).@AfterReturning(pointcut=; \' b6 B0 H6 u i: N, m
“com.javakc.spring.schemaaop.TestPointcut.t4() && l' Z. v, T' J0 d% I2 l
args(str)”, returning=”retVal”)
6 {- A* n: y# t. _0 U @AfterReturning (pointcut=”com.javakc.spring.schemaaop.TestPointcut.t4() && args(str)”,returning=”retVal”)
6 ^& y: _5 _/ H T public void testAfterReturning(String str,Object retVal){
( p' v- U! z3 {; C, X' {: Q# k* ? System.out.println(“afterReturning1=>”+retVal+”=>”+str);
4 E/ G& c3 \& w2 Z/ W7 A }
) K2 e% p, @6 H! P/ G' R 5.4.2.@Aronud3 v4 T6 N4 A8 ]$ k% `. l' x
注解@Around环绕追加功能;6 R( Q! I1 f5 T9 B% P
在执行目标对象的方法的前、后追加功能;3 \$ D2 e7 _; t# C; {+ A5 j
必须有参数;第一个参数的类型必须为ProceedingJoinPoint;& z4 ?% @; N- p* m' Z3 \) {
通过ProceedingJoinPoint的实例的proceed来调用所监控的
' w( g8 q# h# I4 j+ V) } 目标对象的方法9 a, g) M5 v! R# y( l: l
1 定义一个pointcut,通过方法名来作为pointcut的名称来引用; J( [' R( r' e' T" F' k: D& h
(1).@Around(“com.javakc.spring.schemaaop.TestPointcut.t1()”)
# o. \" E0 q4 t$ x (2).@Around(“com.javakc.spring.schemaaop.TestPointcut.t2()) v! M5 V7 N! ^
&& args(str)”)
) |8 S! G* x4 E& T 2.直接引用匿名的pointcut* K8 \( B( r8 V& R2 M
(1).@Around(“execution(8 g1 c; E# D7 i. L2 W6 l. a* u
* com.javakc.spring.schemaaop.Api.test1())”)
; c' Y/ t0 N; }- h4 C- q- J (2).@Around(“execution(
5 n0 R7 G( x% f) u! J9 M * com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”) ^; Y# V8 V# G* y+ o
// @Around(“com.javakc.spring.schemaaop.TestPointcut.t2() && args(str)”)$ [+ p( J2 a0 J+ y$ Y
@Around(“execution(* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)+ B6 z* F- x9 W a
public void testAround(ProceedingJoinPoint prj,String str) throws Throwable{
# ?. Z, f6 e+ ?. X9 E System.out.println(“around1==========before1pointcut==>”+str)
& `, j5 _) q4 ~ Object obj = prj.proceed();9 G/ P' \1 d. m+ k; S. V3 b2 E' E
System.out.println(“around1==========after1pointcut==>”+str);# U* n1 ~1 u% d: h) |' \( D
}
2 e% D9 T; x. s v 5.4.3.@Before
6 q2 N, R; U @: n1 X3 b 注解@Before在执行目标对象的方法前追加相应的功能5 M! i- c; t! o
1 定义一个pointcut,通过方法名来作为pointcut的名称来引用
7 [' r5 p2 e( B/ q$ h8 I' }, J (1).@Before(“com.javakc.spring.schemaaop.TestPointcut.t1()”)
7 s$ }1 {1 ]6 j (2).@Before(“com.javakc.spring.schemaaop.TestPointcut.t2() && args(str)”)
7 a7 c. p9 c2 o, o 注意args后的名称与参数名相同
7 x/ k3 A, k7 @5 S! |& C9 u 2.直接引用匿名的pointcut" y! \. e& V$ ^* t
(1).@Before(“execution(* com.javakc.spring.schemaaop.Api.test1())”)
' _! D+ a( Z) ^4 H' K$ _* [5 l# B (2).@Before(“execution(* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)4 R M1 n* \5 C8 R+ }
注意args后的名称与参数名相同
# J3 p/ ]( N3 ? // @Before(“com.javakc.spring.schemaaop.TestPointcut.t2() && args(str)”)* z9 T" [4 x8 t! i z2 t# P6 z ~
@Before(“execution(* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)3 v6 X ?. b; D) @; F
public void testBeforeParam(String str){
" e6 P' Q V* a, H6 P2 c! E System.out.println(“before1=param=>”+str);
* L& C8 o. \* P& c6 M }
# U6 s- f/ `; p) L& h( t1 {; ]& V 9 T" o1 b9 q+ g( ^! e
5.4.4.@After; u( d8 {6 p. U2 R
注解@After在执行目标对象的方法后追加相应的功能
2 _) P% j2 J. K" \# L 1 定义一个pointcut,通过方法名来作为pointcut的名称来引用
9 \' l# S: d0 b. k% u1 P1 D (1).@After(“com.javakc.spring.schemaaop.TestPointcut.t1()”)0 V9 `/ j$ S- q$ ]9 N: P) Q
2.直接引用匿名的pointcut& b/ b# ?* K+ b) b4 h* ]6 C
(1).@After(“execution(* com.javakc.spring.schemaaop.Api.test1())”)* {+ u( s" A; {1 w
@After(“com.javakc.spring.schemaaop.TestPointcut.t1()”)
9 y, @ e+ Y: }2 g9 x- I5 U public void testAfter(){
& S, k# q! p+ B/ E3 A! X5 j System.out.println(“after1== >pointcut”);& \1 `) H! M: _: m# {. v
}- y- m `; T0 v" q* |9 R
5.4.5.@AfterThorwing
6 B9 ^8 J9 K b# E- o' w
% ?1 ^* w# h% ~. j! O, L8 I3 y' U: b0 Y% H" M8 b
- 描述一下spring中BeanFactory和ApplicationContext的差别0 J( \1 x2 P1 _( c* T: H/ ~
* P2 b+ d9 S8 w, Z! N; O
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”); 2 }5 d$ i4 [% a4 s2 o/ }, t
- 谈谈spring对DAO的支持' F% L% n# c; g+ Z: t7 T! z; R# D
( U) A W1 v, q( ]
Spring提供的DAO(数据访问对象)支持主要的目的是便于以标准的方式使用不同的数据访问技术。3 G' m$ g+ J: W: q! j) p, n
简化 DAO 组件的开发。
+ ]: @9 R: x7 P% uSpring提供了一套抽象DAO类供你扩展。这些抽象类提供了一些方法,用来简化代码开发。
& w: j. p% _( T$ F" V. Q IoC 容器的使用,提供了 DAO 组件与业务逻辑组件之间的解耦。所有的 DAO 组件,都由容器负责注入到业务逻辑组件中,其业务组件无须关心 DAO 组件的实现。
8 N3 |( V) U+ i 面向接口编程及 DAO 模式的使用,提高了系统组件之间的解耦,降低了系统重构的成本。
- g+ V; i( ?% o, H( Q8 ` 方便的事务管理: Spring的声明式事务管理力度是方法级。, H3 K9 \5 c- P# s/ `# g
异常包装:Spring能够包装Hibernate异常,把它们从CheckedException变为RuntimeException; 开发者可选择在恰当的层处理数据中不可恢复的异常,从而避免烦琐的 catch/throw 及异常声明。
6 C2 s. K% ^! d e2 O: _
/ z5 y: {: n; g1 B! d3 N2 j. K) p) h% Y/ M) S
- 谈谈spring对hibernate的支持
0 x3 ~$ |$ e# i' `6 {, `
d. H8 i8 [, u% I/ I g' y1 l
在所有的 ORM 框架中, Sping 对 Hibernate 的支持最好。如 SessionFactory 的注入、HibernateTemplate 的简化操作及 DAO 支持等。另外, Spring 还提供了统一的异常体系及声明式事务管理等。2 E* i9 r" ^( H& U' F
一旦 Hibernate 处于 Spring 的管理下, Hibernate 所需要的基础资源,都由 Spring 提供注入。Hibernate 创建 SessionFactory 必需的 DataSource ,执行持久化必需的 Session 及持久层访问必需的事务控制等,这些原本必须通过代码控制的逻辑,都将由Spring 接管ataSource, SessionFactory, TransactionManager等,都将作为 Spring 容器中的 bean。将这些bean 放在配置文件中管理。
) \5 Q7 \4 h# F 1、通用的资源管理: Spring 的 ApplicationContext 能管理 SessionFactory,使得配置值很容易被管理和修改,无须使用Hibernate 的配置文件。详细配置如下:
$ t+ ~# z8 l! K8 n
- a$ V7 g2 {$ _! Z# N6 ^ class=“org.apache.commons.dbcp.BasicDataSource”>$ I4 w) l( B: U+ c. S
" n K( O# P9 ~ oracle.jdbc.driver.OracleDriver
+ t; S; q3 x! q9 K/ R1 A5 m5 A 6 Z" i7 l7 ~; J7 o
- r/ ~0 U& X9 v, b/ W jdbcracle:thinlocalhost:1521rcl
X5 p. N$ \- w$ P% s# \$ @' _. i
: c) w( h: t0 R$ L$ k
: {. ^, b: k8 A" u( ^9 R! ?& ]+ t javakc2$ e! z: j- o7 A+ z# B2 @' k w$ a
7 | S; \( g" t. i' @7 {
. N) } Q6 i$ }+ | javakc2- L/ i2 B; {# n8 O8 t7 a
2 m6 L# f, J4 w6 ]2 M
2 t. v, l) Q- P0 @: d
I2 N0 t/ H* r* F$ ` class=“org.springframework.orm.hibernate3.LocalSessionFactoryBean”>* N( G5 d/ ~5 l( W
( e) h; _" _; f b/ | 4 P4 \( F& g: N' L; t. H# M2 S
* w; m3 }- \3 l) b com/javakc/spring/h3/UserModel.hbm.xml
6 k1 L. |( L7 K! `1 {' c. g
}! t. w& v6 m
( s# Q$ X% g. l4 I/ Y0 g
5 T& t6 X+ e) J z 6 n8 Z& C: q! Q7 u
hibernate.dialect=org.hibernate.dialect.OracleDialect
4 ^# J7 o& r! s - `3 D6 H. `: `0 B7 X5 |8 k
: m' D1 L$ D- t4 C1 O' \ 3 u7 s3 L' z4 G) `* G5 J+ H" E
! P' H8 {9 n4 L4 I9 o) i* L8 @/ |
" c" V/ q; ~ K8 Z C2 W# v ; |" h v9 k: w9 L4 O
如果需要使用容器管理的数据源,则无须提供数据驱动等信息,只需要提供数据源的JNDI 即可。对上文的SessionFactory只需将dataSource的配置替换成 JNDI 数据源,并将原有的 myDataSource Bean 替换成如下所示: class=“org.springframework.jndi.JndiObjectFactoryBean”>
. U2 W4 b x% S, M/ J
: g; o! k( X$ |1 J# H! U java:comp/env/jdbc/myds0 A+ c" |& y# ]7 ^" R
! [9 o% a9 z: m 2、有效的 Session 管理: Dao类继承HibernateDaoSurport后,Spring 提供了 HibernateTemplate,用于持久层访问,该模板类无须显示打开 Session及关闭 Session。它只要获得 SessionFactory 的引用,将可以智能打开 Session,并在持久化访问结束后关闭 Session ,程序开发只需完成持久层逻辑,通用的操作则由HibernateTemplate 完成。 3、统一的事务管理。无论是编程式事务,还是声明式事务, Spring 都提供一致的编程模型,无须烦琐的开始事务、显式提交及回滚。 建议使用声明式事务管理,Spring 的声明式事务以 Spring 的 AOP 为基础。可将事务管理逻辑与代码分离。代码中无须实现任何事务逻辑,程序开发者可以更专注于业务逻辑的实现。声明式事务不与任何事务策略藕合,采用声明式事务可以方便地在全局事务和局部事务之间切换。 Spring声明性事务有两种配置方法,一种是xml配置: 1 ~) g% _# d2 |- r+ T) u7 g- V
8 y9 \4 B$ H9 _/ T8 {' y
0 z% n o8 x) b# O m/ [ * X! P; v* R; Y
9 ]; F- J7 r* x" H- q3 } 8 x9 N+ ?; E# F z
) k) t) Y w) D; ]
+ }4 b$ I; m4 W2 Z1 t8 r0 R- E
* @8 ^, M' l2 E3 D0 O: U ' W' b) T, ?, |; n, i6 @
8 z# A, z5 v1 K; h# ]4 u
! K1 B9 f+ J' J y' F) J
. Y: @/ Z2 _, g' U/ k
5 ?6 [$ g7 i: G& b S9 C+ i6 w 另一种是通过注解,在需要添加事务的类上注明 @Transactional
B; n O" I. D1 Q0 sSpring2.0之前事务的写法
7 i4 U& w! S" d5 w1 J$ y" y5 w: ?4 i
5 z3 A/ o1 V0 q; N$ J% p
: G, ^0 L! ~3 A1 A9 {- {3 W class=”org.springframework.transaction.interceptor.TransactionProxyFactoryBean”
8 f2 [1 Q+ r; Q' q9 g m5 f( t
) h7 w% r1 k0 ~6 i2 T2 ]+ Q+ S abstract=”true”>" e8 U! ?$ n; N) U- I$ T1 P
/ p( f2 C5 A: p" M% R
1 e! ^& X* w) U4 k7 P6 a
$ x9 k. x' x& _. C' F: E
) D4 O2 N- ^' x& {9 W# F PROPAGATION_REQUIRED,readOnly2 [4 g: {+ w5 [; U& a; C
6 M3 w( e$ K1 T5 `2 d: O
PROPAGATION_REQUIRED- F$ h% o" m( s( C6 u
0 [# q+ I k5 a q) U, `& f+ ?8 X/ f! ]" o
% y2 ~' C& `% j& t" h7 c$ }
; K3 [0 ? e T% P: \
|
) h4 n- G1 Z6 o8 {; h0 T3 c# w& v) O0 a* _& l f' E
- 谈谈Spring对事务的支持# {, Z* a. M( i( Z" g
+ R9 d: p8 j9 Q9 l6 w
" e# h. _2 T, Z- |1、声明式事务管理:
1.流程:由客户端访问—-aop监控—-调用advice来追加事务 2.做法: 2.1 在配置文件的头中引入xmlns:tx 和schema的文件 2.2 2.3 注入数据源
& C9 x. s- ~% g2 B' i( a2 y4 T, K! o: s; k
P$ k/ n/ _0 ~$ u
3 k0 b* Z/ x! F/ ?$ C+ Q% }3 @9 R- h9 S, u
- t: P: M1 z; m5 ~" z4 h2.4 由spring实现的事务管理,但需要注入数据源 % _; G5 I3 l4 D" @( K
* G" v+ j9 A; M1 H% F3 W$ J/ X( i4 a- d, A
2.5 事务监控所有的方法(事务加强) 9 c3 g2 T$ L: v) P% i7 E8 ?
6 {! x( a# n1 n$ [4 ]
& V% q5 x! N# l3 w3 [) j$ g- Y, A" ?7 p/ E7 G+ h, v8 X) ?' i
8 U1 {; W$ l( c9 W
2.6 定义切入点
# E, m7 E0 [% O4 V) R
: m1 c2 {8 ]( J6 [8 g. p' U
- N$ f5 ~- N' w; X* m
* }. v% X; H5 A
9 W: s$ u, Z$ G* F& [2、使用注解实现事务管理: 1.注解@Transcational (可以在类上,也可以在方法上) 2.在配置文件中同样需要注入dataSource和spring的事务管理 3.使用注解的方法来追加事务 注解驱动
A7 Z' F. `) u" w, z6 l
3 M3 m& Y- U3 F如何在Spring中使用Hibernate的事务:# n7 ^6 s# J+ L
' q' Q$ S# q' G r4 s
2 a4 P( Q: _8 s s6 J7 ^1 @4 E# E 1 S. X ]" b; }3 A: X
如何在Spring中使用JTA的事务:. T' `+ U8 _4 ?0 g
. w9 D$ S+ R* J) Z4 E |