Spring+ ? |) w5 H: s' k+ O3 F
- 是什么? c' Q0 `" [! S4 U2 U
- M8 @4 Y/ X. X& {! m! s
Spring是基于JEE的轻量级的应用框架
( _* `4 i& K7 h# p" k- 有什么?
+ _& c; D F, \7 {" g
- V. [, m; w/ f( E/ T6 [- t: _
& E0 {: u$ }$ n, T$ C0 d2 B$ U
每个包的功能: Spring MVC:spring 本身提供的web 框架 WEB:集成其他的web 应用的框架,或者说是对其他web应用框架的支持。如struts,webwork JEE :集成一系列的jee的技术(对JEE技术的支持) DAO:封装了JDBC;(对JDBC的支持) ORM:提供了对ORM工具的集成(支持) AOP :面向切面编成 CORE:spring的核心包,提供bean的工厂和IOC容器
/ M+ E7 z2 i9 r8 E2 p- 能干什么?) U+ Z9 ?+ |3 E6 m9 p) T. j! j
/ G) _4 \( [* P$ t1 a: z7 [' c
把一系列的jee的技术有效的组合在一起形成以良好的系统 2 [; j. O( }2 {6 r
- 怎么用?' I8 x: {5 ^$ w7 ^, c0 ~& W
8 X5 R! m& {; H; Q5 }3 |6 F
- 搭建web工程,引入spring的jar包$ X* |7 t3 [+ a" H6 m- l1 {8 i
- 在web.xml中添加如下配置
( J" l+ I2 S; f0 C7 r+ L8 ] _. P# M/ J9 o5 }0 P b8 h5 X7 V C3 b# w/ u/ b p
2 E6 h8 E. Q4 m; c9 l# B- `- o& s
1 q/ S, G, x: L* n2 F8 j: S: _* O5 \
contextConfigLocation/ h @3 D) [! o: H8 j7 f" r3 E
classpath*:applicationContext*.xml! ^& |4 w! h4 O" V
( _( c+ @" u2 W, M 7 l' m: d' A, {" H- p
struts20 S ]! S8 L! ] t$ K. i
9 N k1 [% S+ J& y! n3 T" h4 l org.apache.struts2.dispatcher.FilterDispatcher& O' u. L E/ b, |+ F
' z/ O7 m* t E; S
7 W; Q, z8 Z% i/ d3 s) k
( X2 d9 M- ^1 }% ^- c9 X* h9 d struts2
0 c \3 x* z( A% c! I0 g% } /*$ \5 X5 p% {- n" r( V9 @
; f% X/ ^" ^& c
D! ]! H. U( S w# G' D
; Z% c7 O* o: E+ [
org.springframework.web.context.ContextLoaderListener) R# {! D; N6 ?1 ^
5 d9 a$ J; L* z% m2 q- L
- 部署7 `5 L6 X0 Q1 e- G
1 F) f6 L& S4 \
6 [3 Q3 u; R* }& G; y' `1 H Q- m, b' L2 u' {
" I* b, X- {$ m( v6 e- H+ w- 容器和bean. U: D! p( J) O( N: q j: m
Bean :是指受spring的ioc管理的对象称为bean 容器 :(与jee的容器类比) Jee :提供组件的运行环境和管理组件的生命周期(不能单独存在) Spring :提供bean的运行环境和管理bean的生命周期(可以单独存在) ! c6 \( p" |7 {1 ?' r8 C
! A8 s- b4 b- Z" G3 P' `6 U1. 应用程序依赖spring注入所需要的对象 IOC和DI是对同一种事情的不同描述 2.setter注入: 在配置文件中将接口的实现配置为bean在应用程序中注入bean 例如: 在配置文件中
! n# o1 j+ Q* Y4 G( I1 U& l
7 x. _4 j# F8 V8 M! |" k7 |% K
! e+ L9 L8 l: k9 ^$ T6 h6 A在应用程序中 Public DBDAO dao ; Public void setDao(DBDAO dao){ This.dao = dao; } 3.构造器注入 # L( B! O: g0 {0 R+ q; G
4.ref 表示参照其它的bean 在参照的过程中一定要注意死循环 5.自动装配———–〉no 自动装配根据名字来匹配相应的bean 尽量不要去自动装配 6.lookup注入 7.singleton 1.单例模式是整个的jvm中只有一个实例 2.spring的singleton是指在spring的容器中只有一个实例 一个生命周期中只有一个实例 8.DI的优点: 1.程序被动等待,强化面向接口编成 2.切断了对象或组件之间的联系,使程序的结构更加松散,运行和维护更加简单
4 s+ x- L3 q% I- w I8 p5 g- Aop面向切面编程
* o* ?( C$ O7 {( i: j9 L
( U2 v# ?0 L$ i, ~& W9 z
1.AOP面向切面编程 一些较好的模式或者是示例—-范式7 Z1 D, N" y* q! d
切面:一个切面代表我们所关注的一系列的共同的功能点(模块之间的共同的功能点) 2.AOP的思想: 主动—->被动(追加功能)2 ^; Y/ `( b2 c$ }2 g2 W
3.AOP 的概念 n. z! O& T* F: Q7 J! R$ z) ^- v, E8 ~
1.切面 :我们所关注的功能点 2.连接点 :事件的触发点(方法的执行) 3.通知 :连接点触发时执行的动作(方法) 4.切入点 :一系列的连接点的集合 (连接点的模块化) 5.引入 :扩展的功能 6.目标对象 :包含连接点的对象 7.aop代理 :实现机制 8.织入 :把advice和目标对象连接起来 4.AOP的事件机制
8 g! h9 Z/ G/ V, |- l 1.通过切面找出一系列共同的功能点 2.找到目标对象(在标准的spring 中 接口的实现类为target) 3.找到切入点 4.确定连接点 5.通知spring AOP,查询xml文件,通过代理找到advice。 6.由aop代理来实现动态织入
$ Q% z, \: y! I+ J( r
$ z/ W( u' P9 M% a# E6 ^ T ~1 s( j+ Y1 e* ?
/ \/ W% i3 o8 Y2 M' F
( E( ?) g' s6 M- C. @8 }5 X9 v& x3 L
8 P0 u# t, y* t0 Y7 U+ S% _
% B' W) j9 `2 W, ?8 P$ Q" l5. AspectJ3 o# J1 {, u4 Q* Y/ b1 P
5.1.在xml中配置比较烦琐. x/ T/ U# ~& N0 q) K C
所有的入口必须从一个代理(ProxyFactoryBean)开始
+ k6 {( Y7 H L' |! u
7 l; h; H/ g' b+ E, J
2 ?1 m( ~* L; ^* T5 ^
3 d i$ ], U: j& {
5 l/ z+ J% y1 y; F7 [5 Q9 K
9 l4 V0 I% {% e; R4 S( `, _6 O* i% K 6 G% T1 G! `+ [
0 @3 S+ r) l: {
9 u; I6 @9 [% ?* Q7 C/ dexpression=“execution(* com.javakc.aop.MyTarget.t*())”/>3 W2 W% e! q7 }% ^
4 n% W; T% E( N% C
4 O. O- ~! d Y7 U3 n; Y4 ^/ F! U
% O K. s6 k% m$ |% l8 R S5 I0 j4 g4 I
6 R L, l7 K$ [! ^+ E7 o5.3.使用注解的方法相对简单
% V2 H) R3 p4 U @AspectJ的基本语法# I* {7 `0 S8 p! ~
1.@Aspect声明一个切面,将一系列的共同的功能定义成一个切面, [( F# ~/ G! f/ r* c' _
直接在类上定义@Aspect4 P# p, m! e4 k% h, @" q
2.@Pointcut声明切入点
2 n' E% u( P7 ~0 V! a; W4 f 2.1、用一个专门的类来定义pointcut,类中的方法名就是该pointcut的名字
: x) T5 Q" i p3 T8 Q9 s 2.2、可以使用匿名的pointcut
4 X1 E$ L$ ]5 Z" U; |) f3 D 2.3、执行切点的几种方法9 t* {3 s, N' @: D. t
2.3.1 execute(public * 包结构.*.*.(..)) 可以指定到具体的方法, j4 u* M, y+ J* }, g! q( z& O0 L! p
2.3.2 within 指定到包,不能指定到类3 x" r) F0 h8 `, P
within(”com.javakc.spring..*”)! B K& O M8 c9 Q# J# {+ S
2.3.3 this 指定到实现接口的所有的实现类
' j% M$ J7 T. ?/ t- A: U 2.3.4 target 指定具体的实现类
% m0 P) r% N- l3 q+ m) Y; ]; H 5.4.advice的五种类型的示例: k' `$ r5 `; I- V) a4 K
客户端必须从接口走才能得到监控,实现想要追加的功能
0 a8 k: C/ e( i: h1 ^: ] 5.4.1.@AfterReturning(pointcut=”” returning=”retVal”)
; w, \) X E9 {- R2 S1 D 追加的方法的参数名字一定要与retrning的名字相同
9 U. I0 c8 `4 n 在注解@AfterReturning中必须加上pointcut和returning两个参数
) A9 W* \1 X; M2 ^! Y pointcut指所要监控的目标对象的方法. c6 q& X' g, U# B0 m
得到目标对象的方法的返回值,来作为参数,进行下一步的处理,参数没有顺序,按参数的名字进行匹配
. B$ q+ q5 }5 B# {' j 完成追加的功能2 W% i' S# j8 V6 `
1 定义一个pointcut,通过方法名来作为pointcut的名称来引用$ c R X# B7 M& r* U" s
(1).@AfterReturning(“com.javakc.spring.schemaaop.TestPointcut.t4()”)$ E, O+ Q# c, N) A
(2).5 H/ O/ K7 F: Q. h# ?
2.直接引用匿名的pointcut( Q) B5 d* I0 f9 P; s) e2 X- m9 |
(1).@AfterReturning(“execution(' l7 z# M3 j: C9 w
* com.javakc.spring.schemaaop.Api.test4())”)) B$ |; h1 H5 d6 V1 l9 U1 ~
(2).@AfterReturning(pointcut=! |( I+ l R1 e& o. `
“com.javakc.spring.schemaaop.TestPointcut.t4() &&- ]9 T2 t! |3 U+ a6 U/ L0 [
args(str)”, returning=”retVal”)
1 r9 S$ x& V1 k% X8 c! G5 @ @AfterReturning (pointcut=”com.javakc.spring.schemaaop.TestPointcut.t4() && args(str)”,returning=”retVal”)# O% T) X8 E% `; {
public void testAfterReturning(String str,Object retVal){$ Q5 _3 [! ^5 _9 V
System.out.println(“afterReturning1=>”+retVal+”=>”+str);3 m( Z; w& f. K$ z* L
}
x& o' W% e5 F" g5 a7 C: h 5.4.2.@Aronud4 O7 [. m! ?4 [% B
注解@Around环绕追加功能;8 e! t b; D% P: M, u* g3 [
在执行目标对象的方法的前、后追加功能;
4 r' z$ `8 i. D) @! G w; { 必须有参数;第一个参数的类型必须为ProceedingJoinPoint;
) r y2 a. M& \1 u/ ?: W% F1 b2 a 通过ProceedingJoinPoint的实例的proceed来调用所监控的3 y: ~% S7 p. B; d* q' \# L: Q
目标对象的方法7 S4 J6 |4 O b$ c! {
1 定义一个pointcut,通过方法名来作为pointcut的名称来引用
, z0 f4 B; f' \7 a (1).@Around(“com.javakc.spring.schemaaop.TestPointcut.t1()”) Q3 c$ ?4 ^/ @+ \; E' b5 x
(2).@Around(“com.javakc.spring.schemaaop.TestPointcut.t2()
. q% w! h. {# g6 p && args(str)”)0 A; b0 x' J$ m1 K) A! y
2.直接引用匿名的pointcut
( r V: n& e7 i! y7 a (1).@Around(“execution(
1 L" d- O7 i2 T5 l @5 W% e * com.javakc.spring.schemaaop.Api.test1())”)
1 o% z* d% H: \) X; i# g (2).@Around(“execution(1 @ I+ {: H: u* q
* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)0 ?+ R; R; y# b5 h. @9 J
// @Around(“com.javakc.spring.schemaaop.TestPointcut.t2() && args(str)”)
% \1 E5 |. \* I" l- U) | @Around(“execution(* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”); a2 {3 D% y* F( b% C
public void testAround(ProceedingJoinPoint prj,String str) throws Throwable{
# z$ h7 M p+ R% t' ? System.out.println(“around1==========before1pointcut==>”+str). S4 L, \$ I; @9 i' ^" ?
Object obj = prj.proceed();! z( k- M7 M5 T
System.out.println(“around1==========after1pointcut==>”+str);6 T( Q- L8 S( S$ V" h. J
}
) U( H" n) D1 ] 5.4.3.@Before
, L/ [, G# Q" n9 f! E+ t# P 注解@Before在执行目标对象的方法前追加相应的功能& N) E- K; B$ x C7 r ^0 w3 J
1 定义一个pointcut,通过方法名来作为pointcut的名称来引用 L( |6 E% L" N( T; t- V
(1).@Before(“com.javakc.spring.schemaaop.TestPointcut.t1()”)
$ _& _; I+ _* q! x! l, v (2).@Before(“com.javakc.spring.schemaaop.TestPointcut.t2() && args(str)”)
* T% Z; F( y8 c3 k3 \ 注意args后的名称与参数名相同6 |# S) m) l4 {' N
2.直接引用匿名的pointcut
4 x3 f. M) M& e' B: C& p" ~4 @+ T1 y (1).@Before(“execution(* com.javakc.spring.schemaaop.Api.test1())”)7 R$ z/ w! r- f, P6 V! B5 c
(2).@Before(“execution(* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)% Z* ^1 r5 K+ f4 c' u) u
注意args后的名称与参数名相同
* [: V9 m& ?, m4 Q // @Before(“com.javakc.spring.schemaaop.TestPointcut.t2() && args(str)”)% A/ f5 {8 i7 g( { H3 K# p. P
@Before(“execution(* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)8 P7 L* x1 A% k- @
public void testBeforeParam(String str){
5 v. [1 b6 ~3 I, R! N# M. F System.out.println(“before1=param=>”+str);$ c/ T$ B$ t# S
}
% p6 {. z1 p9 k8 x W0 f5 H
( X% C5 _, B+ k! F5 I5.4.4.@After
9 v% o5 ]% I# h$ H& I 注解@After在执行目标对象的方法后追加相应的功能
9 U g+ |; @) q& y! Q 1 定义一个pointcut,通过方法名来作为pointcut的名称来引用
* Z2 c9 |3 Q" k, d$ ~1 J/ u (1).@After(“com.javakc.spring.schemaaop.TestPointcut.t1()”)
' \( H1 A& A* H2 V 2.直接引用匿名的pointcut& Z6 g* Q" t* X4 Z
(1).@After(“execution(* com.javakc.spring.schemaaop.Api.test1())”)- e) S6 {7 C1 q, o% G$ f
@After(“com.javakc.spring.schemaaop.TestPointcut.t1()”)! y9 _5 M2 [* w- h
public void testAfter(){
, d; t# C; `' b5 U% o System.out.println(“after1== >pointcut”);
7 y3 A; x( E3 n. q$ f }
+ d- b+ J, t0 {0 ?% C5 i4 u# X 5.4.5.@AfterThorwing
/ d/ _. M/ C& }' R( A* n$ t% ]5 ~: d 3 o% y8 G3 u2 _* u; _. \. q
6 R3 C( b7 L* u. ?$ I+ f, `; e
- 描述一下spring中BeanFactory和ApplicationContext的差别
- c3 L* P h/ R7 K! J, g* E, Q2 ~6 [1 T/ P" Q2 `! p. m* I# N
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”);
! N* n# q% h& H) O/ O' f- 谈谈spring对DAO的支持/ j$ ~) J, j& ~+ ]* |' j
* ?7 s/ Z7 j. G( z" y" v
Spring提供的DAO(数据访问对象)支持主要的目的是便于以标准的方式使用不同的数据访问技术。
0 J: n# {. i, ^7 k# V8 P6 j 简化 DAO 组件的开发。
' P" ]3 J8 f; p! RSpring提供了一套抽象DAO类供你扩展。这些抽象类提供了一些方法,用来简化代码开发。
' ~$ a4 Y) Z9 u$ P1 K IoC 容器的使用,提供了 DAO 组件与业务逻辑组件之间的解耦。所有的 DAO 组件,都由容器负责注入到业务逻辑组件中,其业务组件无须关心 DAO 组件的实现。
$ \* S! c: f& [* |$ }, ?) w2 D. T 面向接口编程及 DAO 模式的使用,提高了系统组件之间的解耦,降低了系统重构的成本。/ i* Y4 K/ W' z5 Z* q1 ~
方便的事务管理: Spring的声明式事务管理力度是方法级。
4 T7 R; S9 Z' }5 M) l* i 异常包装:Spring能够包装Hibernate异常,把它们从CheckedException变为RuntimeException; 开发者可选择在恰当的层处理数据中不可恢复的异常,从而避免烦琐的 catch/throw 及异常声明。
% {1 ?) W" u5 P$ D B, H, b, S
& s* I7 [" u2 H( P) ^' `% Z0 r. b
- 谈谈spring对hibernate的支持# t0 Z- @9 n5 B$ s/ Z9 N
0 W7 f( P! @$ ~+ s) R
在所有的 ORM 框架中, Sping 对 Hibernate 的支持最好。如 SessionFactory 的注入、HibernateTemplate 的简化操作及 DAO 支持等。另外, Spring 还提供了统一的异常体系及声明式事务管理等。
/ U6 P% U- i2 y5 P 一旦 Hibernate 处于 Spring 的管理下, Hibernate 所需要的基础资源,都由 Spring 提供注入。Hibernate 创建 SessionFactory 必需的 DataSource ,执行持久化必需的 Session 及持久层访问必需的事务控制等,这些原本必须通过代码控制的逻辑,都将由Spring 接管ataSource, SessionFactory, TransactionManager等,都将作为 Spring 容器中的 bean。将这些bean 放在配置文件中管理。0 Q7 w" @* u, O1 z {( j
1、通用的资源管理: Spring 的 ApplicationContext 能管理 SessionFactory,使得配置值很容易被管理和修改,无须使用Hibernate 的配置文件。详细配置如下:8 g5 J% F/ _3 K# E
# j; H2 k- b) q/ y+ \/ { class=“org.apache.commons.dbcp.BasicDataSource”>
7 y! `; F- X# v! [
! v3 H" j; C" ~( R oracle.jdbc.driver.OracleDriver( n! r5 ?6 x& a7 }
3 ^3 e- \' l3 O) k# s
4 j$ D% @+ ~% T0 P- w: b5 j jdbcracle:thinlocalhost:1521rcl
, M# [8 b4 E1 u
! e2 Y7 _# _: \: ~6 i6 A8 k
0 _7 C! G9 U( q; k i+ G+ J, p javakc2
* D9 e! Q9 n2 K. H; v8 J' k . [1 u* S( r, h5 z
; K/ g' S* a' K7 v7 G
javakc20 y7 i6 _- ^0 r1 _
% X* y3 D' u% X& p- C) \# L" @
- `% y! a* |; o" v ! B: _) s, a# k3 g7 q1 g
class=“org.springframework.orm.hibernate3.LocalSessionFactoryBean”>: z& b5 q4 O1 [4 X7 E
7 o, c* E' F! q$ v( ^
$ A+ M" c; r7 h) P8 q, N
) m: @/ p# H* R* R% G( q$ m
com/javakc/spring/h3/UserModel.hbm.xml
; s- c, f- C! V4 s
" M5 a6 `: g7 |# E) Z$ `
0 r* t3 M3 ~7 p) t
! E/ H3 k( F9 [1 x 4 P2 T' n* I8 Q% q1 |) Z/ s7 v5 f
hibernate.dialect=org.hibernate.dialect.OracleDialect, a( n: V7 @$ R4 `3 `- Q7 `
4 B6 K F/ ?( s( ~9 N/ e. f" q$ P8 l
: ?4 Y* H2 `/ L! n
/ I5 {$ Z# f% N% e* T6 H3 j& b; Z - ~: p% K4 Q! e; x- d
7 x* y/ u8 c7 @! d0 ~
2 e" p w3 ]' b5 [( e; }
如果需要使用容器管理的数据源,则无须提供数据驱动等信息,只需要提供数据源的JNDI 即可。对上文的SessionFactory只需将dataSource的配置替换成 JNDI 数据源,并将原有的 myDataSource Bean 替换成如下所示: class=“org.springframework.jndi.JndiObjectFactoryBean”>
7 h, x! e4 L/ N
) G1 S8 W( O$ O: m3 w5 L java:comp/env/jdbc/myds1 X, P7 }2 G8 U+ y$ g
+ J' P* r4 ~' _. v. m: b 2、有效的 Session 管理: Dao类继承HibernateDaoSurport后,Spring 提供了 HibernateTemplate,用于持久层访问,该模板类无须显示打开 Session及关闭 Session。它只要获得 SessionFactory 的引用,将可以智能打开 Session,并在持久化访问结束后关闭 Session ,程序开发只需完成持久层逻辑,通用的操作则由HibernateTemplate 完成。 3、统一的事务管理。无论是编程式事务,还是声明式事务, Spring 都提供一致的编程模型,无须烦琐的开始事务、显式提交及回滚。 建议使用声明式事务管理,Spring 的声明式事务以 Spring 的 AOP 为基础。可将事务管理逻辑与代码分离。代码中无须实现任何事务逻辑,程序开发者可以更专注于业务逻辑的实现。声明式事务不与任何事务策略藕合,采用声明式事务可以方便地在全局事务和局部事务之间切换。 Spring声明性事务有两种配置方法,一种是xml配置:
0 x8 ], z7 z, T3 \7 `6 N# S
. o2 \4 X7 I( m5 N# |# Q & h6 F- I; G) ^2 X* ]5 A+ J
# ~" O1 O! Q) E& m+ ^. @
& y- u5 g2 m( h5 A; r1 c
u1 f/ [- U: Z+ v9 G
1 t8 e F% |& |2 K# K9 w6 N: u
% N5 R) V& Y3 K' T3 x
: A- N5 y0 K) ~. \( E! k* f4 Z
" n- s" x' p$ C; v1 z
9 L- E- v+ `+ Q0 z& D8 I9 F
: f+ l* a, G* I5 Q9 V
^4 R4 u2 r. {6 C+ b
% w! n# u' j1 Y( M, @$ P 另一种是通过注解,在需要添加事务的类上注明 @Transactional 9 q s- t3 e1 h) l. {
Spring2.0之前事务的写法
* }, s# {7 A# @- I
) c6 V" c0 O7 n9 L6 l3 N" P6 u! W
3 E9 t: ?6 v+ Q class=”org.springframework.transaction.interceptor.TransactionProxyFactoryBean”
3 h+ R! v, W8 `# `8 _
3 w1 p: d: F7 l: w* q9 D abstract=”true”>
) C. S' y0 y* B4 |" z, }7 Z( _# K% U/ A/ s
0 k% Q$ i$ X, }6 ^* P8 `% |7 e
7 f; @7 m q# [% s
3 N& r% N: j9 ^* K, ]- ~/ H
PROPAGATION_REQUIRED,readOnly; B) A+ h0 S" c1 h' |, r
$ n; Q9 q# R8 a7 ?9 }, L' T2 @, K
PROPAGATION_REQUIRED
; M$ _" X* @8 d& q( ]' i9 \: W& D: A* |
. P5 c E; l( f9 v9 f/ M2 ?( ~' T
% e2 E! j% I4 u p
z P7 C' L* k$ G& F+ ~( g
|
" P' ~- M- R* ~) @
' m* S. C- N* }2 O/ l8 o0 t- 谈谈Spring对事务的支持. d* d" W/ _3 i
" k$ s C6 M3 X7 w
( }) ]& }% P0 Y. f
1、声明式事务管理: 1.流程:由客户端访问—-aop监控—-调用advice来追加事务 2.做法: 2.1 在配置文件的头中引入xmlns:tx 和schema的文件 2.2 2.3 注入数据源 0 X& ]# G4 p( e/ Z a: y( } C
1 Q0 E6 h9 V$ @# d; j( O: {& T& S. d' A( _! O
% @% Z4 K! B4 r6 ^3 L& V2 A) f8 m c2 ]
+ I# u/ l5 b7 A m# }
2.4 由spring实现的事务管理,但需要注入数据源
1 H- ^9 g ^3 z1 B8 [1 Q
. J( X8 w! S0 q2 d
/ {/ D# R ]+ W$ ?2.5 事务监控所有的方法(事务加强) 0 W. K0 o( {; d9 L/ X6 a0 ~! K, P
* ^" y+ x, a$ J% x( F" r
/ a; O8 A" V6 L% {' u/ D8 {
8 G) p! H9 F$ u6 p
/ n7 p# b! |- \% O: s8 W+ m; y* x2.6 定义切入点
" ^+ b7 h8 i- [+ S( Z& a+ d0 |1 M9 S0 E, l
* P6 { {7 y6 l1 j; r3 W% Z
/ G- o8 l) D: i5 G/ h: }3 O M$ X! l8 u4 O' t+ D
2、使用注解实现事务管理: 1.注解@Transcational (可以在类上,也可以在方法上) 2.在配置文件中同样需要注入dataSource和spring的事务管理 3.使用注解的方法来追加事务 注解驱动
/ t1 G. s1 o3 i+ J& U$ v8 H7 M# G( P, D d0 J/ K) l! T, ` b
如何在Spring中使用Hibernate的事务:) `6 [+ B, R% O* Z7 Y
6 R# h7 r& n1 F' U2 [$ h7 }
W8 m$ U S; G5 o% R. c
- D/ Z/ E4 C& Q) e
如何在Spring中使用JTA的事务:$ ~/ @; |7 q4 @" C1 { {* v
) E8 X" Z% e# E& k! f/ i
|