Spring4 p+ c( F ?& s" X3 P
- 是什么?# F7 |1 R& n/ w3 X) P
1 p1 N% J e( b- Q8 E) b( s
Spring是基于JEE的轻量级的应用框架
, w Q' {4 C8 Y) |0 D. Y- 有什么?
3 q/ |3 r4 X* R k; l( |- `3 t$ G# n5 n! E
. F3 y4 \8 @% i. s8 ?
每个包的功能: Spring MVC:spring 本身提供的web 框架 WEB:集成其他的web 应用的框架,或者说是对其他web应用框架的支持。如struts,webwork JEE :集成一系列的jee的技术(对JEE技术的支持) DAO:封装了JDBC;(对JDBC的支持) ORM:提供了对ORM工具的集成(支持) AOP :面向切面编成 CORE:spring的核心包,提供bean的工厂和IOC容器 ) U6 j" C: q5 K2 b
- 能干什么?
- ^9 ^ ?9 r H6 U9 u% U6 M( U |% `6 L
把一系列的jee的技术有效的组合在一起形成以良好的系统
" _8 q* B% b# e' e b" h8 d( M. d- 怎么用?& R+ e8 A% N5 `7 ~6 O+ H
3 E( T1 C+ ~' g- 搭建web工程,引入spring的jar包% y5 N. x: a& K3 V3 l' {/ z+ x
- 在web.xml中添加如下配置
) r- T7 D! H2 x3 p1 ^2 Y2 L0 {0 l' r, Q+ J" t1 j
6 ^$ W4 v1 w. p7 H$ K* D
* Y2 Z! f0 {4 w( o& H9 n
contextConfigLocation+ {2 ]( P6 j- K1 u# L& m* \" ]
classpath*:applicationContext*.xml- e" h, E# G4 C
7 d- ~( P6 X% g6 d& v7 O' H) h" a
1 k7 J5 P7 i6 |' Z8 V2 S. x, T
struts28 B- s; w% _8 C
# ^. D& N( O! u8 R org.apache.struts2.dispatcher.FilterDispatcher! Z5 Q* ^$ \# j H; R) |9 D U% F
4 K- c9 C1 _1 O1 |: y7 B0 f
2 ~8 Y- V) ?. g4 m" q/ u" a
8 ~2 i# A6 V( b5 J struts2" a+ U( n4 p0 j* J/ s$ s
/*
$ z: S! b" }8 Q) `
) c N w+ M5 t9 u5 g
( J' b3 C5 _4 \) P* V" [+ h
, G+ h9 S! c) d
org.springframework.web.context.ContextLoaderListener
2 {4 l) D X( G
, M+ {( W$ ?; }, g& T& o# U - 部署 I3 B1 ~, U% _+ b* U/ K3 ^
8 f p% a. V# \' P! E6 O6 x5 k1 Y 5 l4 g$ y+ m- U0 Y1 _8 c# H
2 U9 e5 U+ o V+ p4 N
" V$ {: Y9 g& y/ q- 容器和bean& ~0 n- P1 X9 W: M
Bean :是指受spring的ioc管理的对象称为bean 容器 :(与jee的容器类比) Jee :提供组件的运行环境和管理组件的生命周期(不能单独存在) Spring :提供bean的运行环境和管理bean的生命周期(可以单独存在) 3 Y9 M3 P; s# J0 ?: b' J
3 b# m7 ?$ [2 r# j0 `
1. 应用程序依赖spring注入所需要的对象 IOC和DI是对同一种事情的不同描述 2.setter注入: 在配置文件中将接口的实现配置为bean在应用程序中注入bean 例如: 在配置文件中
, c7 t( O- q; g B; H
2 L! W" g9 z6 e. ]( v
" @8 X8 f! V' |9 N在应用程序中 Public DBDAO dao ; Public void setDao(DBDAO dao){ This.dao = dao; } 3.构造器注入
! \# Q5 s- M) }3 N. h, h" B4.ref 表示参照其它的bean 在参照的过程中一定要注意死循环 5.自动装配———–〉no 自动装配根据名字来匹配相应的bean 尽量不要去自动装配 6.lookup注入 7.singleton 1.单例模式是整个的jvm中只有一个实例 2.spring的singleton是指在spring的容器中只有一个实例 一个生命周期中只有一个实例 8.DI的优点: 1.程序被动等待,强化面向接口编成 2.切断了对象或组件之间的联系,使程序的结构更加松散,运行和维护更加简单
; Y- A3 b( v7 Z% g$ x: ]- Aop面向切面编程/ z6 e$ ]) o6 r3 J" T
1 [ @5 N& R! b4 {( x$ P4 a
1.AOP面向切面编程 一些较好的模式或者是示例—-范式+ r( m/ o% D1 M# r2 H
切面:一个切面代表我们所关注的一系列的共同的功能点(模块之间的共同的功能点) 2.AOP的思想: 主动—->被动(追加功能); f8 E) S* [$ R, @( q- _7 B( q
3.AOP 的概念# t1 {7 W# w1 N: y& s; p
1.切面 :我们所关注的功能点 2.连接点 :事件的触发点(方法的执行) 3.通知 :连接点触发时执行的动作(方法) 4.切入点 :一系列的连接点的集合 (连接点的模块化) 5.引入 :扩展的功能 6.目标对象 :包含连接点的对象 7.aop代理 :实现机制 8.织入 :把advice和目标对象连接起来 4.AOP的事件机制
' R% d3 u4 W' ]* z t' ?, ` 1.通过切面找出一系列共同的功能点 2.找到目标对象(在标准的spring 中 接口的实现类为target) 3.找到切入点 4.确定连接点 5.通知spring AOP,查询xml文件,通过代理找到advice。 6.由aop代理来实现动态织入 1 f8 [. T7 T7 I4 }8 a; Y' ? ?
4 b! o* A* _: h% E8 B& T
3 I( a/ N4 }( w; ^/ g3 q, R8 s; T2 R
1 Q, E4 F) V+ N" @( B4 D# O1 \- S! t# d1 b
7 _9 A: e7 y$ `) G3 Q' y5. AspectJ
. n- E& I0 F* l2 x4 o 5.1.在xml中配置比较烦琐
, k+ G2 \) V' U9 M( j5 r, f 所有的入口必须从一个代理(ProxyFactoryBean)开始1 b6 D" m4 Z, u4 m
0 Q; |6 R! v/ ?' b0 x. j; P @
& b/ c, g1 T* z: y1 b: p
' g8 G( k4 C, }$ F) D5 m2 m9 l
5 P" a0 n+ H3 h$ K! H: x1 T
7 e4 x- H8 q' Y! ^3 X/ E! |
- f1 d- z5 h; x( q4 ~9 u
. O6 S' O3 }: f& A , x) v9 B8 B8 c
expression=“execution(* com.javakc.aop.MyTarget.t*())”/>! b+ Y b- i# u* Y1 d/ S
+ T$ V* I/ b5 W
( q# v; F4 @. [ , p( n: g+ ]: Y& `1 C
1 C4 @6 I) B( p; J' m/ H3 ~
' N1 ^8 K: U* p0 j+ l- }5.3.使用注解的方法相对简单
/ A/ D, u( p3 y% m. e+ I @AspectJ的基本语法
( H4 }7 L, i( r# A) P' r 1.@Aspect声明一个切面,将一系列的共同的功能定义成一个切面/ J6 x" |- G4 S/ r# P" G) Q
直接在类上定义@Aspect
) J u3 n$ J7 C: C5 u 2.@Pointcut声明切入点
- m, K4 V7 e5 U' e8 e1 n4 s 2.1、用一个专门的类来定义pointcut,类中的方法名就是该pointcut的名字
4 y, E* c, x6 C7 U3 A+ f 2.2、可以使用匿名的pointcut
0 g) d5 H, C/ q( S 2.3、执行切点的几种方法
9 d) Z; u1 B, D! R; p; [- X5 j 2.3.1 execute(public * 包结构.*.*.(..)) 可以指定到具体的方法- G+ Y9 L: D, Z4 b8 X, f
2.3.2 within 指定到包,不能指定到类
, I2 I; m; J/ x( n; o2 r5 J9 l within(”com.javakc.spring..*”)& j! d7 p6 @# q8 ^5 \- W
2.3.3 this 指定到实现接口的所有的实现类& ]* G, @) s! ^0 d( S
2.3.4 target 指定具体的实现类2 D- X" [9 w( ~
5.4.advice的五种类型的示例9 r5 B# e4 k$ s0 B
客户端必须从接口走才能得到监控,实现想要追加的功能3 r4 h( \. n7 W
5.4.1.@AfterReturning(pointcut=”” returning=”retVal”)9 `2 x U$ z' S% n8 Q
追加的方法的参数名字一定要与retrning的名字相同( N4 G/ \; A5 Y9 [; ^$ o6 z; b8 v
在注解@AfterReturning中必须加上pointcut和returning两个参数$ B4 U, h$ a- y% t- r
pointcut指所要监控的目标对象的方法
! Q2 Z6 C) E* ^+ Y8 k* S9 J( U5 c 得到目标对象的方法的返回值,来作为参数,进行下一步的处理,参数没有顺序,按参数的名字进行匹配' H, W0 I( j! d5 l) D
完成追加的功能0 {; k6 f: C+ c2 H2 v" @
1 定义一个pointcut,通过方法名来作为pointcut的名称来引用
: q, l4 ~) W0 I! B (1).@AfterReturning(“com.javakc.spring.schemaaop.TestPointcut.t4()”)# k/ y h6 d. K6 V3 E' S
(2).7 C- ~/ K; g5 U' u9 |4 d- u3 D9 a
2.直接引用匿名的pointcut0 a6 F; z: Q+ L) h* c. G
(1).@AfterReturning(“execution(7 G z5 x, n. }# w
* com.javakc.spring.schemaaop.Api.test4())”)
/ A: v1 `: U& v+ d* d) y (2).@AfterReturning(pointcut=0 H8 G% U. @8 z" U
“com.javakc.spring.schemaaop.TestPointcut.t4() &&
3 |3 L9 b6 M0 ~9 a% Q args(str)”, returning=”retVal”)4 ]; e/ f- l! X( {9 v: A
@AfterReturning (pointcut=”com.javakc.spring.schemaaop.TestPointcut.t4() && args(str)”,returning=”retVal”)
& D* m% M( m$ T, V! h" P0 u( e public void testAfterReturning(String str,Object retVal){: p( H8 E- T" n4 N1 k! S# O
System.out.println(“afterReturning1=>”+retVal+”=>”+str);
; r4 k F# F& M9 A }
! V( c3 F# i" A* V 5.4.2.@Aronud% a) j( _/ ]4 u: V" b& U" h$ b4 P
注解@Around环绕追加功能;0 R u1 R4 m8 @0 _
在执行目标对象的方法的前、后追加功能;! \4 r( L& {) T& z0 \/ m8 b$ m
必须有参数;第一个参数的类型必须为ProceedingJoinPoint;! b0 ^2 ^. k/ z6 ?8 d w# L2 M% e
通过ProceedingJoinPoint的实例的proceed来调用所监控的9 H6 E; p; q- ^3 ]& n
目标对象的方法
' y* r; u( J9 t. f 1 定义一个pointcut,通过方法名来作为pointcut的名称来引用
4 z( ]1 t7 C( C; g& c0 g9 S$ { (1).@Around(“com.javakc.spring.schemaaop.TestPointcut.t1()”)
! b8 U7 x+ i$ q (2).@Around(“com.javakc.spring.schemaaop.TestPointcut.t2()- u) o/ k2 p5 D' ^1 a
&& args(str)”)
* a$ i7 J% Q; i+ X: E; o/ j* A 2.直接引用匿名的pointcut# @8 Y; o0 ^) d' a
(1).@Around(“execution(
; Y0 J, f7 V, f, K6 \ * com.javakc.spring.schemaaop.Api.test1())”)
0 f. s5 q* J" U9 d (2).@Around(“execution(9 G: ^% l8 o! j) H- U5 ?; Z- K0 S
* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)
; I6 q' g; W1 H/ _. v3 A* z // @Around(“com.javakc.spring.schemaaop.TestPointcut.t2() && args(str)”)
: F& o$ e9 R6 N N @Around(“execution(* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)9 E3 D$ Y* _( ~5 f# B8 ]4 E" u
public void testAround(ProceedingJoinPoint prj,String str) throws Throwable{
6 R% z5 J4 L6 ^. ]: n System.out.println(“around1==========before1pointcut==>”+str)8 Z k7 H" V; O1 p7 E& Q+ ^9 i
Object obj = prj.proceed();
2 T3 [) J1 _; n, Z% ~ System.out.println(“around1==========after1pointcut==>”+str);. u5 {2 z5 d2 b5 K
}
! `6 Z3 F* ]/ y2 g, l% P) Q* a 5.4.3.@Before+ V4 `/ G: R. p7 \
注解@Before在执行目标对象的方法前追加相应的功能
0 r) D4 \3 Q0 K/ q% a$ k 1 定义一个pointcut,通过方法名来作为pointcut的名称来引用
5 [) y8 |5 k6 `+ h5 N (1).@Before(“com.javakc.spring.schemaaop.TestPointcut.t1()”)
$ U6 M3 Z5 d8 `8 P0 C; _, y! K8 c0 S m (2).@Before(“com.javakc.spring.schemaaop.TestPointcut.t2() && args(str)”)
0 V& ^, S3 X/ C J1 F! G% H8 z 注意args后的名称与参数名相同( R, I7 ]; U6 t1 {6 P6 O4 [
2.直接引用匿名的pointcut
: ~/ r9 J: |# t (1).@Before(“execution(* com.javakc.spring.schemaaop.Api.test1())”)
4 a+ k8 ~$ g7 J/ t (2).@Before(“execution(* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)
& z5 N$ d# q0 |" V, H# C 注意args后的名称与参数名相同9 F% T7 F: E: E! `5 p) j
// @Before(“com.javakc.spring.schemaaop.TestPointcut.t2() && args(str)”)
$ M1 s; l2 J! I( o a" V5 }% z! n @Before(“execution(* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)
! S6 @, B* \/ y public void testBeforeParam(String str){
1 J7 ]0 k0 s) Y) \+ f* r& Y: y, n System.out.println(“before1=param=>”+str);- y& G+ v; k: d+ Q8 j
}- I* L# N; b) f- h& b
; H; P+ i( V: J; {. d
5.4.4.@After7 q/ w+ \+ Z& U9 x- J
注解@After在执行目标对象的方法后追加相应的功能6 ~3 F3 g( [3 h( E. w
1 定义一个pointcut,通过方法名来作为pointcut的名称来引用
0 _! \5 K0 z6 g1 b9 B! C (1).@After(“com.javakc.spring.schemaaop.TestPointcut.t1()”)' I2 {5 p# S+ r
2.直接引用匿名的pointcut
" X' o6 v. n4 g$ @: S8 W0 a6 Q (1).@After(“execution(* com.javakc.spring.schemaaop.Api.test1())”)# c7 O1 j; b. y; o7 V
@After(“com.javakc.spring.schemaaop.TestPointcut.t1()”)
$ u, K4 U8 |# g: _6 O* V) ?$ C% b( W( E public void testAfter(){; O9 s% |' `3 T$ C
System.out.println(“after1== >pointcut”);
! G& F* r9 {! ?; k e3 g9 r }# z' A9 x/ F; ]. p7 U2 S
5.4.5.@AfterThorwing$ D6 _/ O, t6 {1 \* u3 Z3 u
. {- p: l- w8 ] m% \# G
& a9 z6 Z$ d, G/ f+ f0 R4 y+ T7 V
- 描述一下spring中BeanFactory和ApplicationContext的差别# b* v8 s( D7 [4 Q! y1 i
0 K- d; ?7 l: u F. [! q( u% 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”);
5 N5 `4 F2 V; v/ z) p9 C8 D- 谈谈spring对DAO的支持
( D0 N2 C1 y" ~8 y# b' s* t, p4 s7 j: R$ l* A8 ?' J2 M
Spring提供的DAO(数据访问对象)支持主要的目的是便于以标准的方式使用不同的数据访问技术。
% n' K8 x" ?" {8 h9 g 简化 DAO 组件的开发。 |; k ` Z" B+ m
Spring提供了一套抽象DAO类供你扩展。这些抽象类提供了一些方法,用来简化代码开发。
: }2 u3 I/ q5 R1 H IoC 容器的使用,提供了 DAO 组件与业务逻辑组件之间的解耦。所有的 DAO 组件,都由容器负责注入到业务逻辑组件中,其业务组件无须关心 DAO 组件的实现。8 [# L+ n/ L/ m% ~) d) E
面向接口编程及 DAO 模式的使用,提高了系统组件之间的解耦,降低了系统重构的成本。& u/ T1 i, W9 P( ]
方便的事务管理: Spring的声明式事务管理力度是方法级。 i1 L7 u# U$ t0 c, p: B. ^
异常包装:Spring能够包装Hibernate异常,把它们从CheckedException变为RuntimeException; 开发者可选择在恰当的层处理数据中不可恢复的异常,从而避免烦琐的 catch/throw 及异常声明。
+ |" l; y; e0 P( A. g2 r; J% _
# A$ T, U% y/ z: C W/ _( w& M$ s- s$ I0 m. u8 ?
- 谈谈spring对hibernate的支持9 z2 v/ a. Q" S
\! ~/ B- i, O* i8 a
在所有的 ORM 框架中, Sping 对 Hibernate 的支持最好。如 SessionFactory 的注入、HibernateTemplate 的简化操作及 DAO 支持等。另外, Spring 还提供了统一的异常体系及声明式事务管理等。& ~8 a) V; l9 s. R2 O0 I! C
一旦 Hibernate 处于 Spring 的管理下, Hibernate 所需要的基础资源,都由 Spring 提供注入。Hibernate 创建 SessionFactory 必需的 DataSource ,执行持久化必需的 Session 及持久层访问必需的事务控制等,这些原本必须通过代码控制的逻辑,都将由Spring 接管 ataSource, SessionFactory, TransactionManager等,都将作为 Spring 容器中的 bean。将这些bean 放在配置文件中管理。 L2 ?! Y6 y! E5 W e: k
1、通用的资源管理: Spring 的 ApplicationContext 能管理 SessionFactory,使得配置值很容易被管理和修改,无须使用Hibernate 的配置文件。详细配置如下:
% j7 r& f3 e7 k3 l + `4 z8 c) i/ {; j4 f2 G8 ^6 e
class=“org.apache.commons.dbcp.BasicDataSource”>
4 w& ?3 {$ |6 n9 s6 O1 K6 N I
7 w0 S( x; q+ A9 P8 R oracle.jdbc.driver.OracleDriver& M" ^* i# [8 r( G/ Y
3 O+ K6 l4 m# b( A) R) H0 M
6 j$ r6 H4 U- |) r; H& R jdbc racle:thin localhost:1521 rcl
8 N1 y! l8 j& q( V) n9 ~0 k
1 @4 \( M# y( o6 g
$ ]9 b$ T( h# a/ ~! X javakc2( q+ m# a& Z& r5 i% K$ M" U) W! {
2 `* C, R4 t, g% g, q % H+ J! N+ j* z. \5 V+ o; u
javakc2' h4 J7 I3 J+ [" ]# Z
# e/ Q5 [6 E- O: |. `4 _
% I+ K7 y. R( K- a3 p6 r& w8 k5 A
7 k7 u* X2 L' `# i; C9 Q: z% X class=“org.springframework.orm.hibernate3.LocalSessionFactoryBean”>4 b/ C0 Z1 }% _! k# [
+ f! R- w1 t0 I1 X X% x4 v
0 `, _* a, O5 V; W4 d6 _
0 Q0 [$ |1 y$ ~+ N# s9 W. V
com/javakc/spring/h3/UserModel.hbm.xml- Z" \5 M5 }& Q* J1 y3 B
( C e9 r9 E) u6 z' q R& s% t% N: N
+ j$ p+ ]8 O) K' |2 r8 T M3 }) I3 W# \8 w! n& y2 u+ E
2 U1 g. d6 z' ? hibernate.dialect=org.hibernate.dialect.OracleDialect
; T" {" z" l- V3 ], q + p, e9 j' t+ _ U2 c
1 _) J1 E4 H+ r9 h
' e8 q! ]- [$ O5 ]2 Y- c7 Z/ Y0 N4 L & m7 X4 m" h3 B- `
1 n& @3 K6 l2 R8 f
, \) g. R/ ~) q# q 如果需要使用容器管理的数据源,则无须提供数据驱动等信息,只需要提供数据源的JNDI 即可。对上文的SessionFactory只需将dataSource的配置替换成 JNDI 数据源,并将原有的 myDataSource Bean 替换成如下所示: class=“org.springframework.jndi.JndiObjectFactoryBean”>% l' k% b( D6 o; B. ^. P* v6 ^0 g
|8 N# N2 V- v6 X/ u9 x java:comp/env/jdbc/myds! c$ ~1 _! c5 Q0 ^: y9 O4 U
% h0 p1 e4 D9 {& o
2、有效的 Session 管理: Dao类继承HibernateDaoSurport后,Spring 提供了 HibernateTemplate,用于持久层访问,该模板类无须显示打开 Session及关闭 Session。它只要获得 SessionFactory 的引用,将可以智能打开 Session,并在持久化访问结束后关闭 Session ,程序开发只需完成持久层逻辑,通用的操作则由HibernateTemplate 完成。 3、统一的事务管理。无论是编程式事务,还是声明式事务, Spring 都提供一致的编程模型,无须烦琐的开始事务、显式提交及回滚。 建议使用声明式事务管理,Spring 的声明式事务以 Spring 的 AOP 为基础。可将事务管理逻辑与代码分离。代码中无须实现任何事务逻辑,程序开发者可以更专注于业务逻辑的实现。声明式事务不与任何事务策略藕合,采用声明式事务可以方便地在全局事务和局部事务之间切换。 Spring声明性事务有两种配置方法,一种是xml配置: # a& S( f+ ]6 i W( U
+ {, \7 k- ?$ N6 z5 L6 T5 c
7 o- L+ [9 \4 H u: O1 v! b0 g- ]- _$ i
; U5 t8 ]8 e$ b
! }# }, t; p4 u& s9 K8 h9 S
& ^0 j# y6 G& S& x
( H- j5 g d/ u7 A& M * r5 g3 \2 ]4 ?. K* h: H8 o, A& m
: s& n' S9 n% P' [0 o1 L
( K3 n' ^. v& z6 i% T5 I: c
% n+ J/ w Z7 G7 N( k8 \' w7 V
9 k1 v. n3 w9 p6 l$ X ) D6 ~' V0 r" s8 ~6 N
另一种是通过注解,在需要添加事务的类上注明 @Transactional
. w- |/ o0 j1 d; M/ | oSpring2.0之前事务的写法" Z6 O2 Q& I6 M. W- I
5 M( h1 t- r% y6 z# H5 c9 d) W% |: q. c
class=”org.springframework.transaction.interceptor.TransactionProxyFactoryBean”
+ w& P+ } I8 z& W) s: L4 d# i) H# j$ v1 q! h& g7 k0 e3 `
abstract=”true”>
& h9 A% R3 Y! e8 }2 F) _+ ^8 t( n9 G1 ]& d9 w9 n' B0 M, Z
5 k! h8 Z5 Z/ n4 D
% |- Q+ a5 D* T5 w6 I9 U/ _4 d+ w- A" q, t
PROPAGATION_REQUIRED,readOnly- J* s s7 ~* p x6 B( r& i
3 Q% [0 c. y4 n8 j n4 a. ^
PROPAGATION_REQUIRED
$ e, A1 u5 q- {" C+ O0 f0 O& c1 z. B/ F
2 w: W/ t; P" g. k; g
, i* y- m; s0 k3 q$ {8 t7 v& a+ o, O3 i
| 9 y9 z. X. ~: w7 |" M* P
7 a7 D2 {; o: W* w- 谈谈Spring对事务的支持) d3 |- ?* ]' \5 |% D& u2 Q
! ~. n+ H$ d0 x
# A; N+ w1 g; _4 E
1、声明式事务管理: 1.流程:由客户端访问—-aop监控—-调用advice来追加事务 2.做法: 2.1 在配置文件的头中引入xmlns:tx 和schema的文件 2.2 2.3 注入数据源 1 [" ~0 A6 \9 V% H- e7 u$ T
/ \7 p1 d6 s! n& j
1 X5 f. [0 {; E( Z5 t" k3 N( V I' V! r
) |" |, v3 {5 _
7 L1 j. f8 B5 H( W) Z6 o( D& O2.4 由spring实现的事务管理,但需要注入数据源
2 v. Z, g# e: [6 E" H. v/ h! c- W
4 ?3 M. e4 s; i
) p) ?1 h7 K, Y. \3 I) g2.5 事务监控所有的方法(事务加强) % b; H9 |7 l$ d
( h2 m6 V6 O1 P
' C. X5 z( A7 e* t
3 H: I4 L6 B% V5 E. O& |- R( G& F1 H/ R
% Y6 n6 ]- P0 E2.6 定义切入点
8 q; T4 Z( ]- e0 M3 ?0 ^+ G$ |' f6 T0 T( l4 q! ]5 k& j% B
3 _4 U' c! k* L R4 @
2 k1 p/ B, c1 t9 q, T! ]
9 W# R3 I$ k/ ]6 y3 F' u6 C4 P2、使用注解实现事务管理: 1.注解@Transcational (可以在类上,也可以在方法上) 2.在配置文件中同样需要注入dataSource和spring的事务管理 3.使用注解的方法来追加事务 注解驱动 ' E, C) K" _; i. Q/ d$ A
: Q Z* ?" p/ V; t$ { N. m
如何在Spring中使用Hibernate的事务:' p3 a8 z) w: _
! ]9 J/ g9 V, N# m( [( r# O- G w( q
1 V! A+ ~7 J0 z" h8 }, M
- t# X" i1 W8 |1 ]- ]( a如何在Spring中使用JTA的事务:/ q( d$ h' m# y" M u" B' y
' Z$ l& h+ t2 g2 {" X
|