Spring
/ y3 N1 A& k! n ?5 O7 ]5 _- 是什么?, C! j% g+ Y6 j$ l) S# x6 p5 P
% q0 d J& O" E7 ^. \- \% l% v/ J
Spring是基于JEE的轻量级的应用框架 * l2 K d" ^/ \5 W2 J9 } `
- 有什么?
) s; J& C! {5 X
% O" P! q% m, ?% D) g4 q/ ?; k5 n
+ B7 r3 Z1 n: z4 H" }- T
每个包的功能: Spring MVC:spring 本身提供的web 框架 WEB:集成其他的web 应用的框架,或者说是对其他web应用框架的支持。如struts,webwork JEE :集成一系列的jee的技术(对JEE技术的支持) DAO:封装了JDBC;(对JDBC的支持) ORM:提供了对ORM工具的集成(支持) AOP :面向切面编成 CORE:spring的核心包,提供bean的工厂和IOC容器 3 |7 t) L g; }# k7 N0 ^* B/ n6 u0 P0 ? v
- 能干什么?) Z* N4 m1 R6 A
; N5 R6 g5 M2 F
把一系列的jee的技术有效的组合在一起形成以良好的系统 ! Y* _! d( O5 t
- 怎么用?
1 g! q/ b' I; Y0 R. }) V2 j( P
6 f j: c: K% X$ [, h9 z) }* t3 x9 W- 搭建web工程,引入spring的jar包8 p( w [" q) V
- 在web.xml中添加如下配置
- W, w& \/ [/ `* Z2 C0 d1 f; c" f' c3 t
. c) d" F* R0 N
2 i: Y4 U/ C! [! Q. j7 h
contextConfigLocation5 {9 w7 t# X' ]( G
classpath*:applicationContext*.xml
# d6 ~5 t# g4 b% K8 K . t% ~7 |6 F$ [' |" E: W! ~
4 f) r0 P( k" g2 h2 i4 ^; x6 i0 X A struts2
/ @4 u. @' ]) s# F l( W$ Q( X
( ]) T1 |% Y3 D! m. ~ org.apache.struts2.dispatcher.FilterDispatcher5 g: Y) @1 J' S, ^ U
$ k+ [2 q0 B1 ?/ B; G' B# a ' R1 B; f3 B, \( G
4 N1 T5 G m7 H E# n struts2 }# s7 A6 x* R; B. }
/*! G6 Z4 A- ?# J. n2 F
3 f+ U- _8 F1 [) M2 n
, z0 m: ^- E2 M! i* R) e5 S* ~# f4 @
7 T! I8 r0 C, \0 f
org.springframework.web.context.ContextLoaderListener9 c- X7 |5 w8 J' h2 Q8 b
1 Q8 U: p0 _0 L( j2 X0 N - 部署/ Y9 x: ~4 J/ o6 w# t" ^4 \5 I
$ O+ X4 @# B2 h7 \5 \8 V 7 V& _+ C+ P# N6 L# Y7 f
, B: J8 w' }3 n% R. m7 L
$ n+ b! V. _6 ]# P+ ?
- 容器和bean
: O f# ]5 u( ^4 L8 s" o: f$ P
Bean :是指受spring的ioc管理的对象称为bean 容器 :(与jee的容器类比) Jee :提供组件的运行环境和管理组件的生命周期(不能单独存在) Spring :提供bean的运行环境和管理bean的生命周期(可以单独存在) 0 F5 d- g/ Y5 N N6 e
( I- G% }8 k& t1 R$ P$ b
- DI依赖注入
4 W1 \& x% S ^; O' X
1. 应用程序依赖spring注入所需要的对象 IOC和DI是对同一种事情的不同描述 2.setter注入: 在配置文件中将接口的实现配置为bean在应用程序中注入bean 例如: 在配置文件中
( p1 T! o8 @4 K2 ?+ B
i5 a/ i9 t! F6 u; f4 H# Z+ d$ B: A
在应用程序中 Public DBDAO dao ; Public void setDao(DBDAO dao){ This.dao = dao; } 3.构造器注入
: v: P: a: B# ?4.ref 表示参照其它的bean 在参照的过程中一定要注意死循环 5.自动装配———–〉no 自动装配根据名字来匹配相应的bean 尽量不要去自动装配 6.lookup注入 7.singleton 1.单例模式是整个的jvm中只有一个实例 2.spring的singleton是指在spring的容器中只有一个实例 一个生命周期中只有一个实例 8.DI的优点: 1.程序被动等待,强化面向接口编成 2.切断了对象或组件之间的联系,使程序的结构更加松散,运行和维护更加简单
( j- W+ B& _5 d% t% Z- Aop面向切面编程
6 a+ @: y( F: l1 c5 |% e/ i
0 _: B. F* Z9 A
1.AOP面向切面编程 一些较好的模式或者是示例—-范式8 `$ O2 m9 \ H+ x6 X; G
切面:一个切面代表我们所关注的一系列的共同的功能点(模块之间的共同的功能点) 2.AOP的思想: 主动—->被动(追加功能)
2 a4 N$ O/ n1 d 3.AOP 的概念
; ]) q5 r' k8 p' w, Q1 C4 J 1.切面 :我们所关注的功能点 2.连接点 :事件的触发点(方法的执行) 3.通知 :连接点触发时执行的动作(方法) 4.切入点 :一系列的连接点的集合 (连接点的模块化) 5.引入 :扩展的功能 6.目标对象 :包含连接点的对象 7.aop代理 :实现机制 8.织入 :把advice和目标对象连接起来 4.AOP的事件机制
- `, j1 K" a$ R* @/ U 1.通过切面找出一系列共同的功能点 2.找到目标对象(在标准的spring 中 接口的实现类为target) 3.找到切入点 4.确定连接点 5.通知spring AOP,查询xml文件,通过代理找到advice。 6.由aop代理来实现动态织入
3 z9 H3 l& r! [
9 M% k% Q: v( Q3 u' R
' F A8 c/ J3 h6 m5 v
' W( d6 l4 [5 g# n$ P, B( \1 q l) g; L
+ g- y. w% h2 w) r6 R! t, j
- U% z2 e- B# v: P. ]/ e, [, q5. AspectJ
7 Z* X; a: w/ F 5.1.在xml中配置比较烦琐
( U: b3 u, C' Y: p+ i 所有的入口必须从一个代理(ProxyFactoryBean)开始
# a8 H, y$ z1 O9 L* N# y( q 9 z7 o8 _/ K6 y1 M7 d
v( G4 I' a3 z+ j- z8 J4 x
l% P0 c; O6 D+ r+ d+ B2 j- e
$ b2 P% Y# h. x
! F+ o% r9 w0 M0 a
! o, }; j( I# c, M2 {! a4 u& N
: m& K7 H7 \5 {' f" G+ O 9 y3 M/ g* W; B% u% F) I9 q, I) f
expression=“execution(* com.javakc.aop.MyTarget.t*())”/> l- T, t5 b: o9 z9 G6 ]' ~: G6 |8 ~
0 r9 f7 N' o7 _# y. U( y w* Z4 } / @1 I: D0 Q& F; |5 `! ~! `
9 j2 z. u0 M3 V& H% K. ]/ Q, Y( o 4 p1 N. F- B/ M3 [7 f$ b8 [+ r$ W' S
) l8 ?% J. J, b7 |4 G G5.3.使用注解的方法相对简单
( Y4 H3 [7 g9 t2 ]2 T) F @AspectJ的基本语法
" Q# S; r/ I4 b" H! A0 K 1.@Aspect声明一个切面,将一系列的共同的功能定义成一个切面# A- P/ Z( [# m5 @/ o1 C* d+ K
直接在类上定义@Aspect
`7 Z; E" ~" U+ d B4 ` 2.@Pointcut声明切入点% g6 o' ^5 A7 v
2.1、用一个专门的类来定义pointcut,类中的方法名就是该pointcut的名字( h" F% G; p; C) I
2.2、可以使用匿名的pointcut) F* S6 m) c+ c
2.3、执行切点的几种方法' B6 Y' G% ]3 x0 b2 K
2.3.1 execute(public * 包结构.*.*.(..)) 可以指定到具体的方法
; c% f: u5 H6 N% l 2.3.2 within 指定到包,不能指定到类
9 n. R8 [6 \- V( u/ h: H within(”com.javakc.spring..*”)
4 U- N2 s1 `4 _! s# F' K" p 2.3.3 this 指定到实现接口的所有的实现类
# K3 c9 U3 `9 B8 e. e# y 2.3.4 target 指定具体的实现类9 `6 T7 J( U. Q. L
5.4.advice的五种类型的示例
) _$ Q5 r; c! R4 O0 R 客户端必须从接口走才能得到监控,实现想要追加的功能
* @4 a: c5 Q2 ~ 5.4.1.@AfterReturning(pointcut=”” returning=”retVal”)1 D" y2 m. E, h/ u: [$ [% ?
追加的方法的参数名字一定要与retrning的名字相同
5 f7 R- J& H) X5 T0 v5 q" |5 N' c 在注解@AfterReturning中必须加上pointcut和returning两个参数2 }, o9 V2 s- C% C- ?/ B
pointcut指所要监控的目标对象的方法
! U4 ^& ~7 }' f# W 得到目标对象的方法的返回值,来作为参数,进行下一步的处理,参数没有顺序,按参数的名字进行匹配0 F) |5 U K+ W* ^: y+ P
完成追加的功能3 \4 ~ @8 {% [0 S. B
1 定义一个pointcut,通过方法名来作为pointcut的名称来引用" [3 Q/ g1 T! F3 Y! ?& T( y! R
(1).@AfterReturning(“com.javakc.spring.schemaaop.TestPointcut.t4()”)
" I; t: d& Q6 P L (2).
9 y, I2 {, N, O9 [ ~ 2.直接引用匿名的pointcut6 h! s. G7 }. _- z, X+ K) [: d
(1).@AfterReturning(“execution(- h" l2 Y" x8 v- s# T0 K
* com.javakc.spring.schemaaop.Api.test4())”)
) I0 j5 V; j# \$ t1 a& b (2).@AfterReturning(pointcut=
6 D, a" F! a( u7 c" ^ “com.javakc.spring.schemaaop.TestPointcut.t4() &&
5 W' K8 r# m9 b2 F0 n! e8 s0 z$ `0 r args(str)”, returning=”retVal”)
" m [/ Z# \; n% O+ G! m t- O1 k2 { @AfterReturning (pointcut=”com.javakc.spring.schemaaop.TestPointcut.t4() && args(str)”,returning=”retVal”)
t4 P# W( F+ N$ Q6 T& p5 e: \ public void testAfterReturning(String str,Object retVal){
{1 E, f6 u# V) ` System.out.println(“afterReturning1=>”+retVal+”=>”+str);6 E2 l8 B }- ~: |9 X7 d5 d. I
}2 W- o; X0 I2 X5 d
5.4.2.@Aronud
. ^: r1 l1 T% h' r 注解@Around环绕追加功能;( D. p- n+ y8 ^) V0 l7 K
在执行目标对象的方法的前、后追加功能;+ A, H+ ~3 u: f; B9 D
必须有参数;第一个参数的类型必须为ProceedingJoinPoint;8 p1 l6 \( h" t# Z4 y
通过ProceedingJoinPoint的实例的proceed来调用所监控的3 f' W4 s- s# V$ j
目标对象的方法
$ v0 r6 E7 c5 U) F 1 定义一个pointcut,通过方法名来作为pointcut的名称来引用
% h5 J2 K! H2 O' Z8 E* k2 Y& N6 X (1).@Around(“com.javakc.spring.schemaaop.TestPointcut.t1()”)$ k0 b% Z5 C f, V2 J6 c" i( ^- X
(2).@Around(“com.javakc.spring.schemaaop.TestPointcut.t2()5 i8 Z0 l0 Q; e/ U# J2 B
&& args(str)”)/ v& u$ {7 F/ k, a5 K4 e& ^ w
2.直接引用匿名的pointcut
% q% X# A* V! Q' G+ N (1).@Around(“execution(0 i7 C0 D- k5 B. Z8 B
* com.javakc.spring.schemaaop.Api.test1())”)
0 M2 F/ |/ [( B0 A, F5 |: r (2).@Around(“execution(
3 C9 p; b- a" Z9 n! ` * com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)
* g2 h( r) I9 b // @Around(“com.javakc.spring.schemaaop.TestPointcut.t2() && args(str)”)
8 V2 U1 r& v" `% {3 U/ X9 Z) S @Around(“execution(* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)4 U o1 t1 O- X, D3 s+ x/ @; G7 U- O
public void testAround(ProceedingJoinPoint prj,String str) throws Throwable{
; \4 s6 [4 j1 |7 _5 ] System.out.println(“around1==========before1pointcut==>”+str)
+ m4 {1 y* d4 k2 K. H Object obj = prj.proceed();* f6 e) _: z8 w+ Z1 |" D
System.out.println(“around1==========after1pointcut==>”+str);+ K* `( S2 J1 H0 f
}4 @. s: \! o, i# Z" A
5.4.3.@Before F1 s, L5 x& R4 W3 F$ d, ` O( D
注解@Before在执行目标对象的方法前追加相应的功能% J; s, |: X2 L2 c
1 定义一个pointcut,通过方法名来作为pointcut的名称来引用$ A! N( a# {6 ^
(1).@Before(“com.javakc.spring.schemaaop.TestPointcut.t1()”)
. _3 A1 T! X: h) G (2).@Before(“com.javakc.spring.schemaaop.TestPointcut.t2() && args(str)”)' y) L: e& y( Q. a: m
注意args后的名称与参数名相同
. d- T7 z; f8 Q2 t4 w2 ^ 2.直接引用匿名的pointcut
% K' p0 O" x* q, E$ l/ u/ D; N (1).@Before(“execution(* com.javakc.spring.schemaaop.Api.test1())”)
; H% X p/ | J# }" T" X (2).@Before(“execution(* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)
/ Q: z2 ^3 @: |( V$ k- | 注意args后的名称与参数名相同
; C2 Q; Q) [' t7 n // @Before(“com.javakc.spring.schemaaop.TestPointcut.t2() && args(str)”)( T1 x, a3 ^/ a [5 O3 r+ O
@Before(“execution(* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)
7 c1 [& r' q) Y1 j( y) W public void testBeforeParam(String str){$ \3 l# q; v7 Y) `
System.out.println(“before1=param=>”+str);4 \ f5 ~! \7 T1 O
}7 j; y; w$ H" Z; S# s h* `
Y9 T& L' S; N w
5.4.4.@After" h. W y T( X. W& [0 b7 `7 V2 B
注解@After在执行目标对象的方法后追加相应的功能; b! _( q1 L0 J. w$ P
1 定义一个pointcut,通过方法名来作为pointcut的名称来引用% q9 K& N- U& \ F7 F* [( n C
(1).@After(“com.javakc.spring.schemaaop.TestPointcut.t1()”): q: |$ d) S- j
2.直接引用匿名的pointcut) b8 P* _0 M6 j, e
(1).@After(“execution(* com.javakc.spring.schemaaop.Api.test1())”)9 y) t7 E: D8 v6 A
@After(“com.javakc.spring.schemaaop.TestPointcut.t1()”)4 X* O0 {. c n0 Q; S* U5 c
public void testAfter(){" q# h; H' p, @2 m4 `
System.out.println(“after1== >pointcut”);
/ \* y; ~' s! {* D( @ }$ U! f7 K3 E6 C0 ?* Z% L( ]0 {6 W
5.4.5.@AfterThorwing
/ v9 n1 N0 n! j! p, C; c+ v % @+ p x: a* U& W* E, _0 ~
8 e' W- D( A. @1 H
- 描述一下spring中BeanFactory和ApplicationContext的差别
( e# m$ N( N/ H" C$ X- V3 K' d* a- |
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”);
% d) }* ^& ?5 P5 R, D- 谈谈spring对DAO的支持/ V; K8 l( o( R% m5 H+ M
: b. Y0 G/ U: e |( {
Spring提供的DAO(数据访问对象)支持主要的目的是便于以标准的方式使用不同的数据访问技术。$ `/ R& x% [8 f; f1 {7 p7 U# f
简化 DAO 组件的开发。
1 K2 B5 I7 l+ |; ~Spring提供了一套抽象DAO类供你扩展。这些抽象类提供了一些方法,用来简化代码开发。
4 I: N1 K0 E5 S) j- b; D: e IoC 容器的使用,提供了 DAO 组件与业务逻辑组件之间的解耦。所有的 DAO 组件,都由容器负责注入到业务逻辑组件中,其业务组件无须关心 DAO 组件的实现。* G7 I1 d' M' F% `! }/ H4 c
面向接口编程及 DAO 模式的使用,提高了系统组件之间的解耦,降低了系统重构的成本。7 _5 I8 j6 t. z, ?% l8 @
方便的事务管理: Spring的声明式事务管理力度是方法级。( Q- O* }1 A+ R) X- ~' {
异常包装:Spring能够包装Hibernate异常,把它们从CheckedException变为RuntimeException; 开发者可选择在恰当的层处理数据中不可恢复的异常,从而避免烦琐的 catch/throw 及异常声明。5 R* g$ W5 k0 P9 R
7 z' W0 {- N# K% b2 l5 ~% M, e
1 u H5 g7 Z* p% l( Y2 O$ N- U
- 谈谈spring对hibernate的支持' H# Z* p0 U& b6 ~5 O) w6 w
[( M" ^2 g& c4 M# i9 k. ?: I
在所有的 ORM 框架中, Sping 对 Hibernate 的支持最好。如 SessionFactory 的注入、HibernateTemplate 的简化操作及 DAO 支持等。另外, Spring 还提供了统一的异常体系及声明式事务管理等。
- j# E/ e: m! a' a* x) k 一旦 Hibernate 处于 Spring 的管理下, Hibernate 所需要的基础资源,都由 Spring 提供注入。Hibernate 创建 SessionFactory 必需的 DataSource ,执行持久化必需的 Session 及持久层访问必需的事务控制等,这些原本必须通过代码控制的逻辑,都将由Spring 接管ataSource, SessionFactory, TransactionManager等,都将作为 Spring 容器中的 bean。将这些bean 放在配置文件中管理。9 r: p& g9 F/ S# }% z
1、通用的资源管理: Spring 的 ApplicationContext 能管理 SessionFactory,使得配置值很容易被管理和修改,无须使用Hibernate 的配置文件。详细配置如下:
# B. F2 e- ?' g# Y
2 v& ]( Q0 X8 C/ E; ~) k* j class=“org.apache.commons.dbcp.BasicDataSource”> n2 \8 j' U! ?
4 `3 i3 q* `9 q# ^" q0 t/ }1 V" ~ oracle.jdbc.driver.OracleDriver
% [+ G. t6 b' z" Y, S
2 _/ c2 ?& O7 q1 B( P j ) N E0 @% ~2 Y3 ]8 j1 ~# u- x1 k/ |
jdbcracle:thinlocalhost:1521rcl
& r$ K# N4 R6 k& [" C$ J, m8 M
i8 B, E0 {; `1 B( y
$ ~' Y- q+ T; b& ~% S javakc2
& E2 g6 j7 H) y9 q J0 k7 {
8 H$ j; z+ [. W$ E! X5 X
$ y6 P4 m. z6 _' X1 Z0 e javakc2+ S! p) G- P9 R- o! R* I. f
7 V4 D+ _3 ]0 f+ n
k0 ^3 L& ^2 h
0 t2 ?6 x* C& a class=“org.springframework.orm.hibernate3.LocalSessionFactoryBean”>& [ N) Z4 v/ n% N
8 K1 L) z' [# [- [8 k3 I! N
: o! |9 t6 H5 v D5 e 8 Q2 J7 u- a/ ?
com/javakc/spring/h3/UserModel.hbm.xml
! }6 O4 ]1 Z: E9 ~# F
2 ^: ?+ d+ f/ H; j3 x! p* _- y
5 W) C) k. {6 @# _7 p- L
: R7 Q+ D; {" y& |7 i6 ~, l; ^ ( T1 p. N, w! B) o* T
hibernate.dialect=org.hibernate.dialect.OracleDialect+ A8 \. l$ m5 C+ L+ v4 ^
) b2 {( [ P0 L / f/ a' b; T4 w! \9 }9 [
. j2 Q+ V$ U+ T# Z2 i7 ~0 H/ W" z
2 b1 n9 D) P- ?1 e' O # y) d; j7 U+ O: ]( m
( Q% ^. F+ F9 h L 如果需要使用容器管理的数据源,则无须提供数据驱动等信息,只需要提供数据源的JNDI 即可。对上文的SessionFactory只需将dataSource的配置替换成 JNDI 数据源,并将原有的 myDataSource Bean 替换成如下所示: class=“org.springframework.jndi.JndiObjectFactoryBean”>! @5 H8 w& e' j! M& v
* p8 z. @9 h$ B! N
java:comp/env/jdbc/myds- c: r! e' y& C: l8 _" o
9 J* J! ^! Z) E 2、有效的 Session 管理: Dao类继承HibernateDaoSurport后,Spring 提供了 HibernateTemplate,用于持久层访问,该模板类无须显示打开 Session及关闭 Session。它只要获得 SessionFactory 的引用,将可以智能打开 Session,并在持久化访问结束后关闭 Session ,程序开发只需完成持久层逻辑,通用的操作则由HibernateTemplate 完成。 3、统一的事务管理。无论是编程式事务,还是声明式事务, Spring 都提供一致的编程模型,无须烦琐的开始事务、显式提交及回滚。 建议使用声明式事务管理,Spring 的声明式事务以 Spring 的 AOP 为基础。可将事务管理逻辑与代码分离。代码中无须实现任何事务逻辑,程序开发者可以更专注于业务逻辑的实现。声明式事务不与任何事务策略藕合,采用声明式事务可以方便地在全局事务和局部事务之间切换。 Spring声明性事务有两种配置方法,一种是xml配置: % G5 v0 `% L: T$ g6 M$ Y
6 y: C: B' u3 W2 r+ m* y+ H
' x9 p7 s* X% D8 d$ E
% A8 ]/ W6 I1 f2 L+ S- |
6 \: @# e3 X% R8 d2 S
" |' ]9 @2 }* |" X
_6 C7 o5 A( r- O
5 H, r4 \+ h3 m8 V" g. ]
1 ?7 a3 p5 R* C9 N$ P
$ h" [8 y" J) ?: Q0 p$ Q! g0 V 2 V# v" P3 E, l# l
. |6 z/ X, }& C3 o, N
* C( V4 K2 Y$ t$ z; ~, W
1 U6 d/ Z0 ~1 y; F/ F! c: ` 另一种是通过注解,在需要添加事务的类上注明 @Transactional " w% w' H( Q5 Q1 Z0 @1 N/ [
Spring2.0之前事务的写法
+ A; I& O% f9 `( @( e' i6 C
% T0 K; H" p5 ~; x0 ~& v1 i( |' {" e- ]) |: D) Z: d
class=”org.springframework.transaction.interceptor.TransactionProxyFactoryBean”
, v( F5 S2 G' E8 M4 y, q1 H
0 _. w( d7 Q* n! J* z& s abstract=”true”>4 k+ _- h* Q& i, }- @( H
; @! C- I# [/ K/ S0 J. Z
: w6 q9 ~& ?- V; V5 o/ c) ^
* G1 l& Z0 D- o! D5 m5 j/ P) A& M0 J
) R& Y3 y2 V& Q7 j- x! f' r PROPAGATION_REQUIRED,readOnly, s3 e1 F! H# n& H- n: o0 h* Y) L
- c/ v8 j5 B- u: T+ Y
PROPAGATION_REQUIRED
, C1 _9 X, P% I! B
; ?. E, |* _( A. m* b" G$ v8 E( M( Z3 F9 F' N3 J$ G; N
9 d" ~& ]" ^+ W* v: {6 w
- F, D+ m4 v) n) B6 p/ T6 J: N
| ( m9 u. ]2 o& y( t. Y n: U
+ i# x# U- p) U
- 谈谈Spring对事务的支持
- ]8 E4 l3 b; c# h" k4 X' u- i% b/ n! p% C
' ?$ U" E# _0 C# c+ Q
1、声明式事务管理: 1.流程:由客户端访问—-aop监控—-调用advice来追加事务 2.做法: 2.1 在配置文件的头中引入xmlns:tx 和schema的文件 2.2 2.3 注入数据源 % T# N3 u. `8 F0 R! B& B* W( n
8 U$ o2 w% I# k3 v- e& v! ]
8 H% M0 A0 }/ n' J
+ |* F0 v+ F1 w% F
; A( g' D* H! W
+ t* j) t- p. H4 r2.4 由spring实现的事务管理,但需要注入数据源 9 _8 `; p" }8 u9 N' a
& [$ J: |3 t* H( V$ p2 g
5 t* w" v& G/ U; G2.5 事务监控所有的方法(事务加强) 4 [2 m6 N1 b8 n0 U- ]4 w
8 `2 B! x$ d- G- {5 a8 Q0 q8 N' p$ o7 [
g, c$ s' k; G) R( V; N, _
% Z/ k1 i$ I& k0 c) b2.6 定义切入点 # d; z3 \& `0 ^) v" U7 c
: c7 V) x1 \# ]8 |- |$ h) H
8 g3 y& T7 D# Y9 G; W# _$ d2 B* c" c1 }3 ^# f9 N
# F- Q5 P+ S6 B2 T0 z/ e' J2、使用注解实现事务管理: 1.注解@Transcational (可以在类上,也可以在方法上) 2.在配置文件中同样需要注入dataSource和spring的事务管理 3.使用注解的方法来追加事务 注解驱动
3 F. e6 T3 Y9 z$ C1 K7 ]6 I! z
% |+ g0 Z/ u; ?! _如何在Spring中使用Hibernate的事务:
9 W: o; w! N* B' G' _7 q
4 B0 U# P" Y7 o# P9 U" B
0 t$ n# k3 |) O" v % F$ n, I: D" t+ e
如何在Spring中使用JTA的事务:/ {5 ~, ]3 f& B
1 E$ ]. |8 }0 X |