Spring# g8 X3 I( |! T% D+ |
- 是什么?$ a6 l- U! R) `" h
U( J2 j6 a; Y7 S- ]+ J
Spring是基于JEE的轻量级的应用框架 & F/ ?' i$ I3 j$ i @) j1 o
- 有什么?
4 T- m0 ^3 N7 T) m: W9 u1 q/ a1 q) _; R( ^$ C
9 E1 W; k5 _% o( k. x1 \$ T! `
每个包的功能: Spring MVC:spring 本身提供的web 框架 WEB:集成其他的web 应用的框架,或者说是对其他web应用框架的支持。如struts,webwork JEE :集成一系列的jee的技术(对JEE技术的支持) DAO:封装了JDBC;(对JDBC的支持) ORM:提供了对ORM工具的集成(支持) AOP :面向切面编成 CORE:spring的核心包,提供bean的工厂和IOC容器
+ h. Z# U( U! o% b- 能干什么?; F" s; Z" b: f- ]
8 m6 d( x* \4 ]" m9 r! _8 h
把一系列的jee的技术有效的组合在一起形成以良好的系统 8 W- w$ C; a Q+ ^. V- t* Y
- 怎么用?, p# e1 ] l4 D# s
8 Z5 `1 o: p* n2 u; ?7 n1 W- s+ \- 搭建web工程,引入spring的jar包
! U9 t) V6 \3 n$ ^& t0 u6 T" O! K - 在web.xml中添加如下配置
1 i! g) b: ~4 P: o' U8 y$ e& Y2 ~. F! l- y4 M' i
9 n. O" f, y1 ~2 _& U5 K( q- A% i5 H, c) u
contextConfigLocation
+ O6 B% \% q P3 V, I8 {9 v; Q classpath*:applicationContext*.xml
- [: d* |8 \: ~. v ~7 b ! F8 i$ C% g) D p; ]4 U& |
E: D9 j+ @# T struts2" R: v: o, c4 J& O8 {
0 y6 F0 `7 Y+ B8 H+ v( e
org.apache.struts2.dispatcher.FilterDispatcher
$ i1 Q" |( `) D. F, a I* |
5 k" A& P! x8 E! j' s j
5 ?4 {1 M2 g, q3 Y, Z" t 9 f) T" o# g) A$ v0 U; v
struts2, w( H5 a2 Q8 Q Z
/*5 h, v" l. _: _
9 r0 y! G4 \* O& @! p
3 O% C2 S4 M) k1 j" _7 k+ P1 Z! R
% }) b& D1 o9 e
org.springframework.web.context.ContextLoaderListener3 P$ z& }$ P8 g7 [
i7 _! ]% r- v
- 部署8 X: K( L% d. e; q; @2 G& _
4 i( J$ g! ^# b3 ^
' X4 R3 w8 d3 n! ?( M' r' K+ v
" a) o& r3 J/ g3 j/ v; X
# x/ }' r9 _* U- R- 容器和bean( y9 ^: _4 P" M& G4 z u% F
Bean :是指受spring的ioc管理的对象称为bean 容器 :(与jee的容器类比) Jee :提供组件的运行环境和管理组件的生命周期(不能单独存在) Spring :提供bean的运行环境和管理bean的生命周期(可以单独存在)
" c2 q' F* T! ?" c( @ s) V* b6 l( m
- DI依赖注入
9 y1 V8 F1 j5 K: h; `, r0 @
1. 应用程序依赖spring注入所需要的对象 IOC和DI是对同一种事情的不同描述 2.setter注入: 在配置文件中将接口的实现配置为bean在应用程序中注入bean 例如: 在配置文件中
* H- J9 x4 D. R/ g Z3 G
6 F3 l% P% w; _# U! g9 j4 K; f# ?7 e+ w
在应用程序中 Public DBDAO dao ; Public void setDao(DBDAO dao){ This.dao = dao; } 3.构造器注入 h, p0 B2 T5 d/ n0 e8 v% N
4.ref 表示参照其它的bean 在参照的过程中一定要注意死循环 5.自动装配———–〉no 自动装配根据名字来匹配相应的bean 尽量不要去自动装配 6.lookup注入 7.singleton 1.单例模式是整个的jvm中只有一个实例 2.spring的singleton是指在spring的容器中只有一个实例 一个生命周期中只有一个实例 8.DI的优点: 1.程序被动等待,强化面向接口编成 2.切断了对象或组件之间的联系,使程序的结构更加松散,运行和维护更加简单
+ H- R; T2 r; m7 ?2 _) t9 g7 S" t- Aop面向切面编程& O# [. w- m6 Q- ?
5 e+ W% E4 g6 v* ^
1.AOP面向切面编程 一些较好的模式或者是示例—-范式# z1 m( S& {6 w1 a; y
切面:一个切面代表我们所关注的一系列的共同的功能点(模块之间的共同的功能点) 2.AOP的思想: 主动—->被动(追加功能)0 i. z) b1 `8 B8 F% C" P: i# Y. K
3.AOP 的概念
\3 z( I1 _( T" f- e 1.切面 :我们所关注的功能点 2.连接点 :事件的触发点(方法的执行) 3.通知 :连接点触发时执行的动作(方法) 4.切入点 :一系列的连接点的集合 (连接点的模块化) 5.引入 :扩展的功能 6.目标对象 :包含连接点的对象 7.aop代理 :实现机制 8.织入 :把advice和目标对象连接起来 4.AOP的事件机制
. g6 f% t2 P) n5 e: L0 S, Q, Y$ X 1.通过切面找出一系列共同的功能点 2.找到目标对象(在标准的spring 中 接口的实现类为target) 3.找到切入点 4.确定连接点 5.通知spring AOP,查询xml文件,通过代理找到advice。 6.由aop代理来实现动态织入
5 t3 W! U& H4 a: \% y$ B' Z3 p* }2 p0 h3 {5 Q4 ^" T$ n. ?( u4 T/ d
9 ~' s+ n \- J7 m4 i2 L! o; y- i2 a. A ~
& o9 T/ R: R% e* u) w
# R0 `. U& o: y9 O/ r& K
. T9 m; o, K |7 y& z, f
5. AspectJ
+ I2 s4 n; S' t i3 @7 |! r9 O 5.1.在xml中配置比较烦琐
3 m3 J3 V0 G3 C2 U$ U7 I; J' z 所有的入口必须从一个代理(ProxyFactoryBean)开始" s4 w& A- J! i" `
` W$ u' S1 S8 f8 ]* U 1 c" s1 z! f) @+ j' U
( X3 g. E A) }$ B
! S# }' u" Z9 D7 M% Y: C. s( H
/ H) C/ t' E. u/ _; S) V
9 z n- i" N* Z5 G. }' U% W
; E/ h- {, C* E4 s2 B/ m, O 2 g) }6 {9 Y. j# H3 H
expression=“execution(* com.javakc.aop.MyTarget.t*())”/>
' R% p2 F% F3 C, i5 B
. `* {0 }( a! d8 V( G
" B4 t5 |, D6 O# o, p6 y9 j
! P+ `' C# p4 Y7 k" G: J
) F. X+ X8 J2 `6 Z1 E
' j) E2 I6 U: A h4 M p* [5.3.使用注解的方法相对简单0 g+ _) @9 _4 k) }6 i c* N
@AspectJ的基本语法
9 B! N& ~: L1 D! ]- A9 |9 ~7 ?* B5 W 1.@Aspect声明一个切面,将一系列的共同的功能定义成一个切面6 D- `6 [! D2 j% p0 r
直接在类上定义@Aspect
9 k" Q6 [+ E5 B3 a1 d! v! R 2.@Pointcut声明切入点
* A- l! Z4 C8 l1 g5 t2 S6 { 2.1、用一个专门的类来定义pointcut,类中的方法名就是该pointcut的名字9 T: k$ C8 s2 ?% B
2.2、可以使用匿名的pointcut
4 ^+ Z7 H- ~9 {1 P 2.3、执行切点的几种方法
0 D0 @9 |1 E2 ?, n7 h 2.3.1 execute(public * 包结构.*.*.(..)) 可以指定到具体的方法0 R( }* e3 S9 Y
2.3.2 within 指定到包,不能指定到类- |% m |3 C$ I/ T
within(”com.javakc.spring..*”)
. f) N! {: ?: G* n/ L& w8 ~4 \ 2.3.3 this 指定到实现接口的所有的实现类* ?+ K- M# e) e9 u: X4 c+ b
2.3.4 target 指定具体的实现类
0 _9 n2 C$ S' w# p, X 5.4.advice的五种类型的示例5 j2 g7 ^$ ]' c# H; x+ y" o0 @
客户端必须从接口走才能得到监控,实现想要追加的功能
: p* w- z% U& l5 c0 P 5.4.1.@AfterReturning(pointcut=”” returning=”retVal”)
4 m/ g: p2 R; i" k5 G, M6 A8 Z& B/ }5 H 追加的方法的参数名字一定要与retrning的名字相同. j% T9 n+ g( ]; C- f" z, h0 u
在注解@AfterReturning中必须加上pointcut和returning两个参数
' r$ M! i* q) K3 O ]+ H3 i pointcut指所要监控的目标对象的方法; [$ c- R! E( H/ E
得到目标对象的方法的返回值,来作为参数,进行下一步的处理,参数没有顺序,按参数的名字进行匹配4 k! H6 D$ u2 E' d
完成追加的功能
( F" z. g; J! H4 V 1 定义一个pointcut,通过方法名来作为pointcut的名称来引用: M1 s0 I w( k" u9 ~4 I
(1).@AfterReturning(“com.javakc.spring.schemaaop.TestPointcut.t4()”)2 d- n4 Y. W* ]* C. c2 R
(2).( ]! p. ]+ X& O/ C
2.直接引用匿名的pointcut
) Z+ Y4 _1 S+ j6 o (1).@AfterReturning(“execution(+ m4 L& T: C# T7 H; |& f
* com.javakc.spring.schemaaop.Api.test4())”)
4 M& _+ [5 j% u9 R5 }0 o% O (2).@AfterReturning(pointcut=, J# i2 x. r+ K- k
“com.javakc.spring.schemaaop.TestPointcut.t4() &&0 h: E6 e9 a; U z
args(str)”, returning=”retVal”) W5 G& h7 j( G$ o& j
@AfterReturning (pointcut=”com.javakc.spring.schemaaop.TestPointcut.t4() && args(str)”,returning=”retVal”)( I, M7 h; u& E/ Y8 a
public void testAfterReturning(String str,Object retVal){
8 h4 M2 m& R% a4 y# Y System.out.println(“afterReturning1=>”+retVal+”=>”+str);2 I* a$ e# l% r# G8 ]
}
/ x0 K& k# c! W4 v1 h: x 5.4.2.@Aronud
* c" l% z% @& z/ s# B. H) B3 a; Y' z 注解@Around环绕追加功能;# g7 j+ W* a8 h* S$ X
在执行目标对象的方法的前、后追加功能;. T9 Y' t7 ~. n
必须有参数;第一个参数的类型必须为ProceedingJoinPoint;
8 l$ _8 U; H/ H 通过ProceedingJoinPoint的实例的proceed来调用所监控的$ p8 Z( B" T! ] x
目标对象的方法2 U8 q/ m% w6 L+ s! |5 w
1 定义一个pointcut,通过方法名来作为pointcut的名称来引用/ p. Z6 D0 Z4 Y+ E/ j+ g" _6 y% a
(1).@Around(“com.javakc.spring.schemaaop.TestPointcut.t1()”)" }8 l. T; M: t
(2).@Around(“com.javakc.spring.schemaaop.TestPointcut.t2()
8 p' u! ?! B# c. ?4 I6 G! S& G && args(str)”)
B6 Z/ E: v- k: t5 v; M; d" P7 x 2.直接引用匿名的pointcut \6 v0 h) l) l, G7 n
(1).@Around(“execution(; v5 x$ F/ ]+ ^9 B. c
* com.javakc.spring.schemaaop.Api.test1())”)# C3 w' ^1 u, u, ^" c' q( x
(2).@Around(“execution(+ k; C5 o" g5 ^+ k+ k/ w/ ]
* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)/ J7 I( G! `, y6 g
// @Around(“com.javakc.spring.schemaaop.TestPointcut.t2() && args(str)”)
$ c7 ] A' w/ p1 u/ v o. x @Around(“execution(* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)
6 H( W( h4 o1 j+ j" G9 W public void testAround(ProceedingJoinPoint prj,String str) throws Throwable{
+ G, d+ C: v0 \! B/ G System.out.println(“around1==========before1pointcut==>”+str)
" O+ `3 \: q1 _- N& J; i4 Q5 h Object obj = prj.proceed();0 O% I+ R- l- i& p* C
System.out.println(“around1==========after1pointcut==>”+str);
! b0 x& O6 q7 ^) x! \( i }
1 i, |: Q4 m/ P7 n 5.4.3.@Before
0 @" q! O5 x3 F5 J5 n/ e 注解@Before在执行目标对象的方法前追加相应的功能" Q. C8 r$ O. T! N2 u% e7 T# Q
1 定义一个pointcut,通过方法名来作为pointcut的名称来引用
6 c4 M! e3 I9 G2 z5 l8 I6 I' M (1).@Before(“com.javakc.spring.schemaaop.TestPointcut.t1()”)
1 m" s6 m9 e$ R, c0 q (2).@Before(“com.javakc.spring.schemaaop.TestPointcut.t2() && args(str)”)
* E# r2 r- ]+ F, z# J9 g3 k 注意args后的名称与参数名相同9 U2 c7 m) Q" | k
2.直接引用匿名的pointcut: a* T$ A% q, [' _/ M8 e# g, g8 Y
(1).@Before(“execution(* com.javakc.spring.schemaaop.Api.test1())”)+ {) o8 I9 w# z* O
(2).@Before(“execution(* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)& d* D3 W8 h& d$ n. U" [& C# S
注意args后的名称与参数名相同
" Q) g5 t, }- { // @Before(“com.javakc.spring.schemaaop.TestPointcut.t2() && args(str)”)- J- P9 P9 L7 N7 Z3 z
@Before(“execution(* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)
( ^: c& a$ ]" L1 w! } public void testBeforeParam(String str){
. X/ y- Y; W5 D' c5 D7 x System.out.println(“before1=param=>”+str);% L c, |& J+ v0 f
}; I: C& P6 e6 x3 \) y
0 _( j; u, W$ P% Q! `
5.4.4.@After
9 ?% e3 n* u& Y 注解@After在执行目标对象的方法后追加相应的功能2 j/ k, Q. O. v4 \( h, }0 ^
1 定义一个pointcut,通过方法名来作为pointcut的名称来引用* S9 U* H; @: E
(1).@After(“com.javakc.spring.schemaaop.TestPointcut.t1()”)
x- Q- _( L0 i8 y/ C0 p, W 2.直接引用匿名的pointcut
$ `: g# o+ ~" [4 X' R (1).@After(“execution(* com.javakc.spring.schemaaop.Api.test1())”)
6 V w5 C! {9 j; x* j0 @4 h3 |2 `2 \ @After(“com.javakc.spring.schemaaop.TestPointcut.t1()”)
8 `$ T: r: M8 }3 l public void testAfter(){2 a+ i9 A. V3 w# s
System.out.println(“after1== >pointcut”);
Q9 Y; z$ O5 F$ G& `! K5 ~6 K& ~ }
3 x( C3 h( ^* j! k( W l 5.4.5.@AfterThorwing. k1 J# _( H6 c3 E0 h
( L f4 S7 t9 ?8 O
. s1 }- `! W. C- d9 q8 A1 T2 g# E- 描述一下spring中BeanFactory和ApplicationContext的差别
4 p* ^# ^2 N/ C5 Y. O5 X' z0 T
4 U6 Q% z# B# z' @
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”); , k( C! _8 B p; n1 ^! g X. I6 c/ g
- 谈谈spring对DAO的支持4 d9 W/ s) o- X7 z
$ _* g/ [7 |' h; A- [$ j
Spring提供的DAO(数据访问对象)支持主要的目的是便于以标准的方式使用不同的数据访问技术。
/ G/ y- A3 f! H3 A 简化 DAO 组件的开发。
4 V( q: L! G. ]* q* H) n- HSpring提供了一套抽象DAO类供你扩展。这些抽象类提供了一些方法,用来简化代码开发。: }# ?; d" R+ Z @& f, l+ J
IoC 容器的使用,提供了 DAO 组件与业务逻辑组件之间的解耦。所有的 DAO 组件,都由容器负责注入到业务逻辑组件中,其业务组件无须关心 DAO 组件的实现。) u* q* a7 T- u( U. p+ [0 z0 @
面向接口编程及 DAO 模式的使用,提高了系统组件之间的解耦,降低了系统重构的成本。
1 k. F6 G2 R: X( w; \, W 方便的事务管理: Spring的声明式事务管理力度是方法级。
0 t8 V, y7 C/ M3 j% j: D; w 异常包装:Spring能够包装Hibernate异常,把它们从CheckedException变为RuntimeException; 开发者可选择在恰当的层处理数据中不可恢复的异常,从而避免烦琐的 catch/throw 及异常声明。
! ^" M$ a% F1 p- n: L' F4 [ 0 g: O4 i0 v0 t8 u
$ K8 w9 k* M5 r# U- 谈谈spring对hibernate的支持2 t$ d5 K0 M( a
; H: Y! i% u; O3 \! s
在所有的 ORM 框架中, Sping 对 Hibernate 的支持最好。如 SessionFactory 的注入、HibernateTemplate 的简化操作及 DAO 支持等。另外, Spring 还提供了统一的异常体系及声明式事务管理等。
: d& j( I* K+ o3 }/ A T; U$ s5 L 一旦 Hibernate 处于 Spring 的管理下, Hibernate 所需要的基础资源,都由 Spring 提供注入。Hibernate 创建 SessionFactory 必需的 DataSource ,执行持久化必需的 Session 及持久层访问必需的事务控制等,这些原本必须通过代码控制的逻辑,都将由Spring 接管ataSource, SessionFactory, TransactionManager等,都将作为 Spring 容器中的 bean。将这些bean 放在配置文件中管理。# f0 s; `9 f7 ?) t
1、通用的资源管理: Spring 的 ApplicationContext 能管理 SessionFactory,使得配置值很容易被管理和修改,无须使用Hibernate 的配置文件。详细配置如下:
/ r0 t' ?7 ]& O- O% m 9 s& J8 ?' J' \% m) p$ M
class=“org.apache.commons.dbcp.BasicDataSource”>$ C8 k) a2 Y& Q q
7 `3 ^2 L% x0 R
oracle.jdbc.driver.OracleDriver3 X! }( P; h! t- s9 M* E
& O& e5 P# Q9 K3 r5 l$ E( Z
( Z4 s6 z' c- Q+ d: {
jdbcracle:thinlocalhost:1521rcl
5 T% _) P- F; h( [" B# X0 K6 h
* @& D& i' A4 u3 B. ?
5 r. G6 l4 c! [8 m" L6 ` { javakc2
: B! b# y* {# ^% f3 u. { 8 D6 b5 B, h' C' K! N2 w
! }6 @9 c. l1 q- [ }' X javakc2
0 u( Y( w8 P5 N$ l$ t$ Q/ G% q! `
7 C8 X% U+ U0 R6 |
/ ?* A9 q2 Q# b, H
+ M0 I0 s M* ]5 r& x+ e1 J class=“org.springframework.orm.hibernate3.LocalSessionFactoryBean”>
! o& m0 ] x+ W6 b/ P
5 _8 S8 P7 U G, d3 G8 O0 C* t
; Q$ \7 k6 V B( W7 b 4 H/ ^* n2 ~0 j% G q2 Q4 ^
com/javakc/spring/h3/UserModel.hbm.xml
3 @' W/ S1 i! s( n
6 }& }, X& p" P1 e, m9 e! X( }" D# S ; n2 t3 z \* f9 y
) z% ^, I% ?, ~. a9 H( a& Y+ U, w* N
) ]" E9 ?2 h7 _7 ]( R( q y, G5 M
hibernate.dialect=org.hibernate.dialect.OracleDialect
2 s1 y- |. b( j' {
3 u8 Z! a2 r: M' ?9 D; R; x* \ . V- O* y5 H0 s
+ _* e# P( z ]
8 u" i$ J/ O: }; F/ |: P/ x $ n! P& z: F0 a4 Q5 Y+ D. r
7 i: b' P% h# k- w$ l _; \$ c
如果需要使用容器管理的数据源,则无须提供数据驱动等信息,只需要提供数据源的JNDI 即可。对上文的SessionFactory只需将dataSource的配置替换成 JNDI 数据源,并将原有的 myDataSource Bean 替换成如下所示: class=“org.springframework.jndi.JndiObjectFactoryBean”>
1 ?+ X+ ^' d- M$ {0 k5 s. a
. [ ?0 \5 C3 ]" S% F java:comp/env/jdbc/myds |1 K8 X3 T; X5 C
! U1 `% b% S7 z3 z 2、有效的 Session 管理: Dao类继承HibernateDaoSurport后,Spring 提供了 HibernateTemplate,用于持久层访问,该模板类无须显示打开 Session及关闭 Session。它只要获得 SessionFactory 的引用,将可以智能打开 Session,并在持久化访问结束后关闭 Session ,程序开发只需完成持久层逻辑,通用的操作则由HibernateTemplate 完成。 3、统一的事务管理。无论是编程式事务,还是声明式事务, Spring 都提供一致的编程模型,无须烦琐的开始事务、显式提交及回滚。 建议使用声明式事务管理,Spring 的声明式事务以 Spring 的 AOP 为基础。可将事务管理逻辑与代码分离。代码中无须实现任何事务逻辑,程序开发者可以更专注于业务逻辑的实现。声明式事务不与任何事务策略藕合,采用声明式事务可以方便地在全局事务和局部事务之间切换。 Spring声明性事务有两种配置方法,一种是xml配置: # f/ P6 q" {" n e. }; [- B
4 Q5 W4 Y& e1 B- \
8 s; Q0 M7 F: d
2 \/ r' x* ~$ Z7 x" i; t
( \& u5 {/ `" J2 m" P6 _ * H, c7 w* |5 o5 Y8 ?& g0 P
+ V$ J# j" E" G. ]4 y& j" l / v" o7 V5 }, J3 z: ?0 O9 Q* z
) s5 u" n% S- {: F
' D$ }+ p, O6 L; f! A
9 h4 D9 I: ^3 N : y3 I+ _ T6 N9 @$ W" N
" O: o* Z1 b+ m! B$ [
8 O q8 f1 [. S' T 另一种是通过注解,在需要添加事务的类上注明 @Transactional 5 D- m# I" h+ n7 M& u
Spring2.0之前事务的写法
3 l; C/ C9 e+ ~1 F/ x3 D8 m% f1 r9 z ?
1 ~1 w2 G3 a8 e* W
class=”org.springframework.transaction.interceptor.TransactionProxyFactoryBean”
" P2 W. @- v- v
* g$ J: S2 C! Z1 t4 L+ m2 F6 `2 r abstract=”true”>
, Z. P) T" V, |6 U$ ]: D3 U; j; r. N# j/ ?3 a* s1 @
5 f% ~" [& n- ?0 H
6 {, F% A7 i- p0 {2 {! x4 r8 c
" o5 t$ H# V6 K PROPAGATION_REQUIRED,readOnly
3 a% R$ O+ B8 s3 }2 _; t! u) ~! Y1 u7 K% q* i
PROPAGATION_REQUIRED
4 c p& m9 w5 V5 W2 m' q+ D7 t* O3 L+ @- T
3 `" V8 p8 [8 y2 n
& h3 H/ Q; E8 Z ~% Y" `3 a4 E6 S9 b$ H8 j
|
1 ]& [7 ^/ h4 P
9 \" i# D2 ]6 X5 z; a& K( s- 谈谈Spring对事务的支持, B" ~" X& u$ a) B- Y8 Q
! t/ T [6 V9 d+ |# s5 ?
; @: _( p6 @* ]# N9 m1、声明式事务管理:
1.流程:由客户端访问—-aop监控—-调用advice来追加事务 2.做法: 2.1 在配置文件的头中引入xmlns:tx 和schema的文件 2.2 2.3 注入数据源
7 w. B$ j' f* T% T! c4 \ C6 S# O/ q, W/ V) N0 g
. L; H: b2 _2 G( L
6 h7 w. E5 F/ e( U7 b+ C
, f9 c. ^) Q. ]4 }6 |8 x
9 B1 A8 z [5 v/ A5 C2.4 由spring实现的事务管理,但需要注入数据源
% _6 m$ c* F1 w! u8 ? V4 L8 N. ]2 u; z2 k5 d
! i( |# t5 M7 X% Z2.5 事务监控所有的方法(事务加强) - X+ p) T0 O9 z" M* L+ Y( q
. _( ]4 T# V+ i3 [# u
; n* [( ?( H# k" W' j' L" o! c; o; N( J$ g
6 w3 l: ?& Z$ l1 ~( K# N2.6 定义切入点 / Q1 e' ?5 w8 b* P! u* F
3 Z5 d$ W+ |2 r; Q. |' m
- P+ f9 A4 @# s7 }* `
* k3 o r1 ]' O0 k
0 \$ m, p8 F* r5 o, S2、使用注解实现事务管理: 1.注解@Transcational (可以在类上,也可以在方法上) 2.在配置文件中同样需要注入dataSource和spring的事务管理 3.使用注解的方法来追加事务 注解驱动 , t- L6 u4 A0 d r2 f+ K# ^6 f% E
$ G ^' P+ s) Y2 e y8 J如何在Spring中使用Hibernate的事务:
8 h. l$ {4 Q7 s
! Q* I9 j9 }" _
# m0 b3 E) s: _( E
3 s/ M- F/ |" n) @2 s2 d- e如何在Spring中使用JTA的事务:& ^% x: p: K& Q% k
, B5 A/ l) O6 [3 b8 H1 c$ I |