Spring4 t2 O/ u6 N+ b, J0 [# p& ^$ p
- 是什么?
6 O# _: c5 r$ C* {- g. m4 k$ {2 Q0 x6 {/ Q6 b# Y
Spring是基于JEE的轻量级的应用框架
5 e6 g! y0 y$ D5 I/ o3 s: E8 x- 有什么?
& z: t% K! r% o) h _0 Q# ?( p8 V5 g) U! C3 O/ s
; D9 y7 T& s- m- v
每个包的功能: Spring MVC:spring 本身提供的web 框架 WEB:集成其他的web 应用的框架,或者说是对其他web应用框架的支持。如struts,webwork JEE :集成一系列的jee的技术(对JEE技术的支持) DAO:封装了JDBC;(对JDBC的支持) ORM:提供了对ORM工具的集成(支持) AOP :面向切面编成 CORE:spring的核心包,提供bean的工厂和IOC容器 i' @& E' T/ T$ ~& m$ r6 }6 O& r
- 能干什么?. B$ y2 v8 k- L/ d v/ r- J. Q7 ?" E
/ q$ m; i: X) |) G0 ~
把一系列的jee的技术有效的组合在一起形成以良好的系统 ( u& \ p6 }: o2 O
- 怎么用?
- n: s- C( N: ? L5 j6 u! g
/ g8 C. e7 D% t0 ]- 搭建web工程,引入spring的jar包7 z3 Q# M4 n" @! u# y8 u
- 在web.xml中添加如下配置
5 [; V1 [( n# X1 v% z$ w2 |* B% X: S6 A" G- `
2 e" m0 E* S- ^9 G: a, c0 L
( s8 q) B7 o7 }0 m7 t1 n
contextConfigLocation
0 j2 ?. G# H; O/ ^$ V classpath*:applicationContext*.xml' C( ]3 |3 H& k, i
- C' ~' i2 G b/ K" f1 w$ q
+ y8 \. Z: V. c5 t/ P5 |% v struts2
! z, A" {: _& M+ V% ` 2 W; j1 D6 Y! K9 y6 ]- [
org.apache.struts2.dispatcher.FilterDispatcher
2 ], @' Y' I8 t1 c3 E# m
7 u6 e) Q: m+ R- p# h J
$ M: B; { K1 b* F- [
; T _9 P4 k9 y. s4 `& D* O( O& E1 k, ` struts2
; b' X" `; ` z /*
: q' K7 o9 h& I1 b& C+ ?" l8 P ( `& C/ p3 b! K2 @4 } x
/ A' Q3 I+ V; F1 q% `: T3 ]
7 F# U3 k7 i% r, O; n- E. p org.springframework.web.context.ContextLoaderListener1 o; }/ ^/ k! d0 M' o
* ~; A8 K- |0 L - 部署9 J6 H ?) @$ A7 ^7 S$ C( s
4 m2 \ o5 h; Q8 q5 T( b, u
+ n, u( G- W8 q t* e |
: }: Y0 O" M1 j+ `1 X
! D! E$ C* F1 Q" ]! E3 H- 容器和bean
! K& ~: r$ d* q5 Y8 l# f
Bean :是指受spring的ioc管理的对象称为bean 容器 :(与jee的容器类比) Jee :提供组件的运行环境和管理组件的生命周期(不能单独存在) Spring :提供bean的运行环境和管理bean的生命周期(可以单独存在)
# A4 R0 J/ _" z& K+ U0 G% v+ o+ Z1 [2 f7 G8 ~
1. 应用程序依赖spring注入所需要的对象 IOC和DI是对同一种事情的不同描述 2.setter注入: 在配置文件中将接口的实现配置为bean在应用程序中注入bean 例如: 在配置文件中
! A0 P# h& P% n" h% F9 ~4 J! ]1 o: k& [
: E* N# P( `5 z. g
在应用程序中 Public DBDAO dao ; Public void setDao(DBDAO dao){ This.dao = dao; } 3.构造器注入
) \# b0 `: r+ J4.ref 表示参照其它的bean 在参照的过程中一定要注意死循环 5.自动装配———–〉no 自动装配根据名字来匹配相应的bean 尽量不要去自动装配 6.lookup注入 7.singleton 1.单例模式是整个的jvm中只有一个实例 2.spring的singleton是指在spring的容器中只有一个实例 一个生命周期中只有一个实例 8.DI的优点: 1.程序被动等待,强化面向接口编成 2.切断了对象或组件之间的联系,使程序的结构更加松散,运行和维护更加简单
* [, z0 d. ]' _7 k A- Aop面向切面编程7 q+ s+ }' Z# ?8 H6 U" t5 O
/ b/ w% }1 Q2 X3 u1 ?" t
1.AOP面向切面编程 一些较好的模式或者是示例—-范式
5 d2 I3 j9 d* \( [! x$ ?3 [ 切面:一个切面代表我们所关注的一系列的共同的功能点(模块之间的共同的功能点) 2.AOP的思想: 主动—->被动(追加功能)
4 } L/ d$ F$ C 3.AOP 的概念* u ^6 p6 w0 l% P
1.切面 :我们所关注的功能点 2.连接点 :事件的触发点(方法的执行) 3.通知 :连接点触发时执行的动作(方法) 4.切入点 :一系列的连接点的集合 (连接点的模块化) 5.引入 :扩展的功能 6.目标对象 :包含连接点的对象 7.aop代理 :实现机制 8.织入 :把advice和目标对象连接起来 4.AOP的事件机制
9 B( ~: c( i( G1 Q+ q 1.通过切面找出一系列共同的功能点 2.找到目标对象(在标准的spring 中 接口的实现类为target) 3.找到切入点 4.确定连接点 5.通知spring AOP,查询xml文件,通过代理找到advice。 6.由aop代理来实现动态织入 % i: K) X& e( u6 U5 u0 A0 {
9 u* D; S8 c; U1 E$ f3 ?- `) o/ Z* c- B" n6 ?4 |
5 [" f9 n, M6 f" `0 [) O% d/ t5 M" M
1 ?1 Q! z1 v- x9 l$ a
: k3 K5 t+ b0 i' L$ _' m f$ a! @) L& M4 d
5. AspectJ* {7 k4 C& A0 f' n" r
5.1.在xml中配置比较烦琐2 Y7 U6 t+ i1 ~2 [
所有的入口必须从一个代理(ProxyFactoryBean)开始! ^( `3 I4 p" s$ H: I
/ X; V/ B0 R' S
9 s E# K* k" S% O% j0 i. i
) e( Q% K/ {: x1 M. K: p( Q2 I6 E6 T
" j& |5 Q2 j7 g; J# M
1 {8 H: w) y1 Y3 ?$ m
9 D4 z( G6 @) s& p; z 1 f9 w* i' q* y
expression=“execution(* com.javakc.aop.MyTarget.t*())”/>
& @: l3 g0 F+ w$ [; y - j- [1 b- b3 P" M8 o" a
6 p% e4 O9 P& K! @
q+ L( O! x! ~$ Z1 }5 I
% {/ w+ p* k" c/ D* \; l' W- D$ }+ O( H% N) x! P9 R1 I& t
5.3.使用注解的方法相对简单
+ k1 r; h. E% S @AspectJ的基本语法
' o9 |# V' f' @ ? 1.@Aspect声明一个切面,将一系列的共同的功能定义成一个切面
' ]3 v9 m+ d; V% j: }5 {9 K 直接在类上定义@Aspect
2 e3 I) F# v! `7 N& U0 S: K9 I 2.@Pointcut声明切入点* ]1 T6 B* N9 t* i* I2 ]
2.1、用一个专门的类来定义pointcut,类中的方法名就是该pointcut的名字5 I* Y8 t f7 W _# i. h
2.2、可以使用匿名的pointcut
3 {9 q. L; a( V' z+ }: {1 { 2.3、执行切点的几种方法6 k5 J% j3 [' I. \& x& U4 @3 _7 F
2.3.1 execute(public * 包结构.*.*.(..)) 可以指定到具体的方法
2 W9 x" V- ^7 M/ v 2.3.2 within 指定到包,不能指定到类/ i i7 D( T# K# {1 C8 k
within(”com.javakc.spring..*”)
* G" ^/ B L' D% @ 2.3.3 this 指定到实现接口的所有的实现类( J8 F8 _ g$ `! m6 M/ B
2.3.4 target 指定具体的实现类# [& v$ Q8 ?- ?8 b5 u! z+ [" G
5.4.advice的五种类型的示例
" S! p( [8 y& Y0 Z 客户端必须从接口走才能得到监控,实现想要追加的功能
3 y6 Y9 @# a2 \+ C$ w3 } 5.4.1.@AfterReturning(pointcut=”” returning=”retVal”)0 z! o" x) r4 z) c
追加的方法的参数名字一定要与retrning的名字相同- y! z/ u$ _9 o0 e
在注解@AfterReturning中必须加上pointcut和returning两个参数3 W, y# {8 n9 ]5 k! o- Y
pointcut指所要监控的目标对象的方法
/ n8 K! h! q% _; e& |( i 得到目标对象的方法的返回值,来作为参数,进行下一步的处理,参数没有顺序,按参数的名字进行匹配
$ C2 }( r" q1 C# i( F V# v/ E 完成追加的功能
0 |2 ^4 U6 Z" V& |: D1 i 1 定义一个pointcut,通过方法名来作为pointcut的名称来引用
! I0 k6 [' l6 w- I$ L (1).@AfterReturning(“com.javakc.spring.schemaaop.TestPointcut.t4()”)3 R1 ~! ~2 q2 x" j _2 Z
(2).
- F: V2 I9 e& ~0 b 2.直接引用匿名的pointcut
4 c9 I, q) Y: a. g) Y% R (1).@AfterReturning(“execution(* K4 K0 l4 T F2 W0 E. E. F" [
* com.javakc.spring.schemaaop.Api.test4())”)6 l' z* U. U; t* w' g. m$ b* O
(2).@AfterReturning(pointcut=
% b# X* k0 N2 S: R “com.javakc.spring.schemaaop.TestPointcut.t4() &&$ x T; s' u/ k: w* b6 ]
args(str)”, returning=”retVal”)6 a9 J! Q+ `# g+ H) m# \% H: d
@AfterReturning (pointcut=”com.javakc.spring.schemaaop.TestPointcut.t4() && args(str)”,returning=”retVal”)9 q1 X; ~; [! L+ C9 V+ n1 y" s
public void testAfterReturning(String str,Object retVal){5 h- M' J4 W# t
System.out.println(“afterReturning1=>”+retVal+”=>”+str);* {5 r5 n( M: P6 @( t$ @
}
3 z' T2 y+ t N7 d+ Y6 e 5.4.2.@Aronud
0 |' [! G# Y! f# N& G$ A 注解@Around环绕追加功能;; f" c, w- C( a5 P Y/ I* D
在执行目标对象的方法的前、后追加功能;
: m6 G4 c0 j( [$ n4 o6 k 必须有参数;第一个参数的类型必须为ProceedingJoinPoint;
. t& P- T: O4 g0 Q' i3 P 通过ProceedingJoinPoint的实例的proceed来调用所监控的: J: x8 W/ [7 L1 I
目标对象的方法( e! g# k% V$ l1 o9 j" G6 `: k
1 定义一个pointcut,通过方法名来作为pointcut的名称来引用( B0 n l1 `9 B( w
(1).@Around(“com.javakc.spring.schemaaop.TestPointcut.t1()”)' m8 l) L% b( \4 G
(2).@Around(“com.javakc.spring.schemaaop.TestPointcut.t2()
; B8 U% P& p t" o && args(str)”)
f' I5 }7 ~" u! V2 T 2.直接引用匿名的pointcut
% L. w' o. H3 T! ? (1).@Around(“execution( O; w2 I' H( f2 q" S1 s" n
* com.javakc.spring.schemaaop.Api.test1())”)2 j3 u4 L3 @8 s$ A ?0 l9 x B+ J
(2).@Around(“execution(4 a# H; M) C- o; b
* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”): G9 ?7 T. p0 \0 p: Y
// @Around(“com.javakc.spring.schemaaop.TestPointcut.t2() && args(str)”)! Z7 N5 g% X, q& W# }
@Around(“execution(* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)
. P) ?! N! T8 R public void testAround(ProceedingJoinPoint prj,String str) throws Throwable{6 o* @2 o, f3 _0 a3 e& ]6 I% J/ i
System.out.println(“around1==========before1pointcut==>”+str)
. }+ y6 ~" z8 U5 e Object obj = prj.proceed();. C* T% V, P0 L' e* a/ O
System.out.println(“around1==========after1pointcut==>”+str);
8 k! _6 {4 L2 j$ C- V }( L2 j8 b( [4 r! z4 B* c0 U! D
5.4.3.@Before/ V8 {% N0 W3 x
注解@Before在执行目标对象的方法前追加相应的功能
1 Y7 ]3 F; i H9 Y( v) X U. z) {# k% z 1 定义一个pointcut,通过方法名来作为pointcut的名称来引用
+ ~0 b7 Z: x9 q- e+ g4 _! J/ p (1).@Before(“com.javakc.spring.schemaaop.TestPointcut.t1()”)
% {: a; g- T# s' F |' n (2).@Before(“com.javakc.spring.schemaaop.TestPointcut.t2() && args(str)”)# ?4 n; P, l% _) A3 p" y
注意args后的名称与参数名相同( B* y% P+ \( ^2 ?
2.直接引用匿名的pointcut
" G0 x( i: v: G1 \. l# k, h2 j: M (1).@Before(“execution(* com.javakc.spring.schemaaop.Api.test1())”)
, n1 {) C5 |, N( L7 r n* k( l (2).@Before(“execution(* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)
2 m6 U$ e6 j7 A) @+ L; T1 p/ b" s 注意args后的名称与参数名相同! q. d- g: W# A! X. K+ ?% n- T
// @Before(“com.javakc.spring.schemaaop.TestPointcut.t2() && args(str)”)( e9 i1 } d+ Z% F
@Before(“execution(* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)
. C, c+ M) k$ l public void testBeforeParam(String str){
* z6 z2 _- @9 [( i0 N: Q System.out.println(“before1=param=>”+str);
- O8 I1 R* X7 @' v }8 i2 d1 g+ v8 Z! v Q7 h
4 {0 M. f. q5 f
5.4.4.@After
! p3 P# D4 ^2 l; G" K% O, [. s1 F 注解@After在执行目标对象的方法后追加相应的功能5 ?$ A. i) l0 N* R& Z, X& E
1 定义一个pointcut,通过方法名来作为pointcut的名称来引用' B0 ^4 V# {4 I7 O
(1).@After(“com.javakc.spring.schemaaop.TestPointcut.t1()”)
. }: s# R( o0 |, I! k 2.直接引用匿名的pointcut
- j: @/ ^" |! B (1).@After(“execution(* com.javakc.spring.schemaaop.Api.test1())”)
+ j- v; L! k! P( j6 j @After(“com.javakc.spring.schemaaop.TestPointcut.t1()”)
2 F! \* M5 a# V9 f" s public void testAfter(){
1 r9 j e: c7 {+ a- I2 l( } J System.out.println(“after1== >pointcut”);! K( j" l: s* J; k9 o b; z, D1 S
}) e, j, T# s& K7 `" E: T" t
5.4.5.@AfterThorwing
) p% i6 w8 |+ Z7 O- j4 v& r1 ^* q % t+ l2 x( B5 E+ J/ A+ [- d
+ u6 B" z7 r: _, q$ e6 {! [$ ~
- 描述一下spring中BeanFactory和ApplicationContext的差别
" P2 j" k; Y4 g3 z: P2 }
* D9 g, M% Y3 i- s
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”); ' F+ \) v4 L' c% f
- 谈谈spring对DAO的支持
( O4 l- ?. f$ s; p8 P9 P" Y
" H _% s4 l. z0 U3 X
Spring提供的DAO(数据访问对象)支持主要的目的是便于以标准的方式使用不同的数据访问技术。0 J, k. @- m" T# M m( i( m
简化 DAO 组件的开发。
" k, a* @ `+ _7 v' ]. ]* D* TSpring提供了一套抽象DAO类供你扩展。这些抽象类提供了一些方法,用来简化代码开发。: B, t. g. T% ]0 b! z8 j1 l3 G
IoC 容器的使用,提供了 DAO 组件与业务逻辑组件之间的解耦。所有的 DAO 组件,都由容器负责注入到业务逻辑组件中,其业务组件无须关心 DAO 组件的实现。
# j8 Z: O$ E7 ^* F2 C; S 面向接口编程及 DAO 模式的使用,提高了系统组件之间的解耦,降低了系统重构的成本。
9 C" S5 ^( ` H1 A* m B 方便的事务管理: Spring的声明式事务管理力度是方法级。' `. w) I" ]; s* }* n9 ?$ j3 ~
异常包装:Spring能够包装Hibernate异常,把它们从CheckedException变为RuntimeException; 开发者可选择在恰当的层处理数据中不可恢复的异常,从而避免烦琐的 catch/throw 及异常声明。
6 V- U9 W- U6 I0 k' O 9 M( _; ?/ v( \5 C5 n/ \
. ?, R* ^ C+ w
- 谈谈spring对hibernate的支持+ C8 f* H" Z! F( Y, B0 q4 _0 g
?* j* A( |% ^& P8 I4 V$ d
在所有的 ORM 框架中, Sping 对 Hibernate 的支持最好。如 SessionFactory 的注入、HibernateTemplate 的简化操作及 DAO 支持等。另外, Spring 还提供了统一的异常体系及声明式事务管理等。, Z5 ?6 _* Q/ t& _# o9 |6 \
一旦 Hibernate 处于 Spring 的管理下, Hibernate 所需要的基础资源,都由 Spring 提供注入。Hibernate 创建 SessionFactory 必需的 DataSource ,执行持久化必需的 Session 及持久层访问必需的事务控制等,这些原本必须通过代码控制的逻辑,都将由Spring 接管ataSource, SessionFactory, TransactionManager等,都将作为 Spring 容器中的 bean。将这些bean 放在配置文件中管理。
3 @7 D5 }5 X! N! R# t0 v 1、通用的资源管理: Spring 的 ApplicationContext 能管理 SessionFactory,使得配置值很容易被管理和修改,无须使用Hibernate 的配置文件。详细配置如下:: f) r! c6 D* s5 M$ A6 r% E7 d
6 A$ s9 x/ u9 _$ D0 w4 D% e
class=“org.apache.commons.dbcp.BasicDataSource”>0 b$ W( U8 M) v/ _
; ~& n8 \" f; b4 Q6 Y. _9 b2 s
oracle.jdbc.driver.OracleDriver
3 _ _% i- j; o6 ^ $ y! t- T7 b8 B7 @; M
: j9 u& i; i4 y* d5 b jdbcracle:thinlocalhost:1521rcl
# g4 D9 M8 g9 E ' W \' J6 Q9 Q9 H
2 P( |1 q! N% A. }
javakc2. n5 V4 B- h5 K! T6 h
9 h* S" M! L# [% w4 |
- e! p0 v; q- z: g+ Q
javakc20 ?, e- d8 }- I4 I6 M6 b
2 E' h$ e f) u9 e, Z; Z9 `
% I. _! A4 m) i# k
e7 `+ h0 q$ Y2 r6 M! P+ K7 [ class=“org.springframework.orm.hibernate3.LocalSessionFactoryBean”>4 |1 H+ h4 u$ w: N; S
. u5 t/ }; F# h$ i B* q
. |" h% ^. q8 y4 ]0 b ( h; e4 I3 H$ f N Z3 b
com/javakc/spring/h3/UserModel.hbm.xml
]; m, d/ ]/ `2 O . [4 Z2 u4 B9 W% o0 Y) r. |
' l T2 u1 |) P) X; ]
/ J/ v* U+ R0 R X
4 ~" U) }) Y9 ^9 z hibernate.dialect=org.hibernate.dialect.OracleDialect
3 ^7 w! ? _8 p2 w1 F
9 _& o/ C& Z. p6 A1 O8 {# M$ F
7 V5 E n% t. X
: B+ f$ y8 v) G8 {% ^
- A& b, G+ }; q 7 w, f6 I5 }7 p" l( s0 R
; J% Z5 w: {, f. ^ 如果需要使用容器管理的数据源,则无须提供数据驱动等信息,只需要提供数据源的JNDI 即可。对上文的SessionFactory只需将dataSource的配置替换成 JNDI 数据源,并将原有的 myDataSource Bean 替换成如下所示: class=“org.springframework.jndi.JndiObjectFactoryBean”>
: @9 A4 @% {2 S) q( F1 w 7 h W* N$ _ C# @5 ~( U
java:comp/env/jdbc/myds
" [' u! q' R* B" t6 R' f
% q- y7 Q P! I: [- U, N9 h 2、有效的 Session 管理: Dao类继承HibernateDaoSurport后,Spring 提供了 HibernateTemplate,用于持久层访问,该模板类无须显示打开 Session及关闭 Session。它只要获得 SessionFactory 的引用,将可以智能打开 Session,并在持久化访问结束后关闭 Session ,程序开发只需完成持久层逻辑,通用的操作则由HibernateTemplate 完成。 3、统一的事务管理。无论是编程式事务,还是声明式事务, Spring 都提供一致的编程模型,无须烦琐的开始事务、显式提交及回滚。 建议使用声明式事务管理,Spring 的声明式事务以 Spring 的 AOP 为基础。可将事务管理逻辑与代码分离。代码中无须实现任何事务逻辑,程序开发者可以更专注于业务逻辑的实现。声明式事务不与任何事务策略藕合,采用声明式事务可以方便地在全局事务和局部事务之间切换。 Spring声明性事务有两种配置方法,一种是xml配置: " x/ A! v' Y \- [4 E' o/ `
5 s; Z; m' e; @6 C0 n5 [
/ J* P4 [ D! t( P3 T
+ c( _4 a1 \1 h4 F! P- z
' `& Z/ M, |: W( [6 W, n
/ y7 \: U' B! A3 b( ?3 a; ? , L$ a* \2 C1 D* q+ v$ I! _0 H
! Q" [! b; g K5 T+ N- e3 f + M5 V6 r+ M# Q
3 ]/ U' ]1 E# k% U
# o6 b+ n$ ]$ b
7 g$ ^" O! k& x
$ V9 U1 U0 q; y2 W+ A; P, K. U
) A0 t$ O% E% a; J* F/ Z7 O8 ~+ H/ o# _4 T
另一种是通过注解,在需要添加事务的类上注明 @Transactional ' p) P4 b8 T0 F# B! u6 W
Spring2.0之前事务的写法
! t$ Q, ~$ l! d! m# w5 r" a3 S4 U2 D% E( J7 `8 H9 P# q
6 K, y: x/ u" J1 k1 E% | class=”org.springframework.transaction.interceptor.TransactionProxyFactoryBean”
: l7 F5 d; ^+ n/ y
9 V8 p- c9 B* R6 a2 h0 ]& X abstract=”true”>9 p' s5 v$ g# J* k1 h( Y
- J/ j. f0 A1 e2 Q2 v7 ]
& Z, d! z O5 t [- v/ Q
' h: q3 W% i+ }6 p5 B) _" J7 g4 K; l/ a+ S) f0 \3 y% y( Q: _
PROPAGATION_REQUIRED,readOnly" M2 w" H/ y# u5 }( x8 Q
2 v7 S- ~5 {( R) j2 i0 A4 [
PROPAGATION_REQUIRED
! y. W/ h7 ]( V% A. `# C; n# R" v
4 E% R. K! Q$ ]6 u! Q& P
5 M0 W: h5 D0 c- I2 C
) L |( N6 ^0 f2 j$ t- {: I- R6 f | 8 l) R7 c" r' u( P/ ~
; c" b+ {" |* z p" z: f$ L- 谈谈Spring对事务的支持
9 [" Z8 m+ K5 w% n3 U7 h; p0 ]( C3 Z# h ]$ O9 \! j
! H& `! T8 [+ S) Y6 |- Y \% I0 x1、声明式事务管理:
1.流程:由客户端访问—-aop监控—-调用advice来追加事务 2.做法: 2.1 在配置文件的头中引入xmlns:tx 和schema的文件 2.2 2.3 注入数据源 0 z* U/ G [' N6 G% C3 e
# b6 l& a9 u6 U2 k( j4 ]" A; v. f- ]7 d, X
4 F5 ]4 r; C& W' F, v9 ]7 H8 Y- e8 K( n4 u
& N' ^- U0 Q" }# D& s: c! U3 r
2.4 由spring实现的事务管理,但需要注入数据源
! ^ l$ U! }" b7 x( @0 Z7 S% F8 Z4 ~( l4 s: a$ X1 V0 G( I& f2 ?- V
6 j/ T, V0 I8 [( V# o$ K5 H8 Q2.5 事务监控所有的方法(事务加强)
6 i: ?, k+ v' R+ g
* r+ }. y+ ]7 h/ J. r2 m; G& u7 V& e4 S% h+ y
g- }7 t" T" X) R
- M6 Z" x i p2.6 定义切入点
# m j9 V( U2 _
1 _5 {- A* b' a) X1 d3 P3 _) v F/ u0 w) C3 |9 R- X1 _& u
6 }* H7 @1 I! `8 e8 ?( S6 d. y
$ {- ]2 j/ m; }% K# r
2、使用注解实现事务管理: 1.注解@Transcational (可以在类上,也可以在方法上) 2.在配置文件中同样需要注入dataSource和spring的事务管理 3.使用注解的方法来追加事务 注解驱动 , V2 U' F+ n p" ?
7 l! Z* B8 L9 g7 ]
如何在Spring中使用Hibernate的事务:7 w) a& X4 k2 }& u! {+ ^
. U: W9 V9 p( e2 V
5 e. R4 B1 I' b
. X" v/ S) x1 [% @$ x如何在Spring中使用JTA的事务:8 c6 Y/ ^) R- b' ?
& W: \$ ?% C0 k/ }2 {& s% d |