Spring- O7 b9 ]4 Q5 a$ {
- 是什么?( Y8 ?. h8 a" S( y1 ^
! \) U5 @$ c8 a
Spring是基于JEE的轻量级的应用框架 ; ~' Z" W* K! @% b
- 有什么?; W) V3 P! R/ x3 x' i& f. h
' `: \8 O& _8 l ]
' y) n5 q5 P; e; \
每个包的功能: Spring MVC:spring 本身提供的web 框架 WEB:集成其他的web 应用的框架,或者说是对其他web应用框架的支持。如struts,webwork JEE :集成一系列的jee的技术(对JEE技术的支持) DAO:封装了JDBC;(对JDBC的支持) ORM:提供了对ORM工具的集成(支持) AOP :面向切面编成 CORE:spring的核心包,提供bean的工厂和IOC容器 ; o- W% M2 T. S5 b# ~& O0 c
- 能干什么?
( d: B' Z8 o5 j% Q0 l4 o* v
9 ~7 i/ v9 y& M! y( E! S9 U1 Z
把一系列的jee的技术有效的组合在一起形成以良好的系统
/ c/ R4 S. }. Q! R- 怎么用?
2 b% l6 `" _' m9 A( S
) x+ X" K- |: j- 搭建web工程,引入spring的jar包
7 a% r9 x% T( \3 ~. K# F g+ i4 E4 A5 Y - 在web.xml中添加如下配置
9 V6 p, d. M& x4 y/ G2 T8 z
0 h- C: j/ u1 e* I' m+ w
& I+ H# y2 a- S# ]1 d' s& t
6 Z y" F& J4 Q1 i6 h# }$ e
contextConfigLocation% N" G; U2 H+ O. A! l
classpath*:applicationContext*.xml( h% z& m# m) f' r$ v/ q
3 [5 ]3 a I/ f; l; r# F( }. J 7 c# r# K( s/ C( D
struts2
g) v' ~: Z; l( g+ O * h& a; e2 U x" k1 W0 }7 K
org.apache.struts2.dispatcher.FilterDispatcher
- t! d& w, I5 j D0 b
$ h$ O# g |9 t, N/ l4 H; E + j) u5 Q0 C# p$ h. l% j% H7 F
# U" T3 J# z. j8 z( L8 @2 O$ ^
struts2
: b: l! g* H3 p8 o /*4 {0 H0 f+ m( \0 M( h' G
1 f$ J- f; x. \
, U% v$ |, m" Y" E/ r
6 b$ ^8 ~6 v; r org.springframework.web.context.ContextLoaderListener
2 W G i8 b4 @. C* L0 w
; \' d/ p+ ~0 i5 s - 部署, a0 l- u+ _, Q$ n
' S7 @/ X# v3 c' T: L+ H
0 F# ]5 @! b/ L1 _4 \' Y7 k+ s" y. N. _3 ]
, N) Z8 ~# A1 s: R! U- 容器和bean
1 c5 r" d2 z8 B: c9 ?# q. G# B
Bean :是指受spring的ioc管理的对象称为bean 容器 :(与jee的容器类比) Jee :提供组件的运行环境和管理组件的生命周期(不能单独存在) Spring :提供bean的运行环境和管理bean的生命周期(可以单独存在)
& E2 n, \1 r! W5 r! z1 L0 u; {1 r7 o& K3 Q5 T, q7 {+ ?1 H
- DI依赖注入( U% p4 \, Z m5 p* F2 O
1. 应用程序依赖spring注入所需要的对象 IOC和DI是对同一种事情的不同描述 2.setter注入: 在配置文件中将接口的实现配置为bean在应用程序中注入bean 例如: 在配置文件中 + e* q6 K. q( t: O
0 ^. j- d0 M: B4 ~1 D) h% m% P0 V4 u& q, Y7 R0 o$ a# \
在应用程序中 Public DBDAO dao ; Public void setDao(DBDAO dao){ This.dao = dao; } 3.构造器注入
% w- _9 F/ e) a. v4.ref 表示参照其它的bean 在参照的过程中一定要注意死循环 5.自动装配———–〉no 自动装配根据名字来匹配相应的bean 尽量不要去自动装配 6.lookup注入 7.singleton 1.单例模式是整个的jvm中只有一个实例 2.spring的singleton是指在spring的容器中只有一个实例 一个生命周期中只有一个实例 8.DI的优点: 1.程序被动等待,强化面向接口编成 2.切断了对象或组件之间的联系,使程序的结构更加松散,运行和维护更加简单
7 ]" S3 K7 d8 u% k8 R- Aop面向切面编程6 U3 H+ }5 n2 b+ p
) E! n* V3 P% U5 `0 F8 L. ]- h u- \) n
1.AOP面向切面编程 一些较好的模式或者是示例—-范式
3 h$ S7 l' R2 a+ q- E( Y 切面:一个切面代表我们所关注的一系列的共同的功能点(模块之间的共同的功能点) 2.AOP的思想: 主动—->被动(追加功能)- Y5 z/ y* Y' N. y$ O
3.AOP 的概念
- l4 a3 V* E! g' p* r 1.切面 :我们所关注的功能点 2.连接点 :事件的触发点(方法的执行) 3.通知 :连接点触发时执行的动作(方法) 4.切入点 :一系列的连接点的集合 (连接点的模块化) 5.引入 :扩展的功能 6.目标对象 :包含连接点的对象 7.aop代理 :实现机制 8.织入 :把advice和目标对象连接起来 4.AOP的事件机制
% f5 {$ a7 [+ W, \2 n$ O9 N 1.通过切面找出一系列共同的功能点 2.找到目标对象(在标准的spring 中 接口的实现类为target) 3.找到切入点 4.确定连接点 5.通知spring AOP,查询xml文件,通过代理找到advice。 6.由aop代理来实现动态织入 ( g& d3 q1 y* ~& f8 A8 m3 ^
7 x; Y0 R8 c5 p; d2 b, H/ ]( c9 `0 X1 D
: P+ h( b( j/ d3 I$ u0 A6 S# m1 S6 l6 w& Q; @1 L- \
, z2 k- K! x' v& W
2 y% e+ @" q: k4 X: A8 J5. AspectJ
7 J3 C& F2 s/ h# |7 L 5.1.在xml中配置比较烦琐+ g5 E5 {: C- A7 F9 M6 o; Y8 k4 S% z! ~
所有的入口必须从一个代理(ProxyFactoryBean)开始
) Z! S6 C2 R* z+ ]
% F. Z" b L; m8 K * p# L* b9 u+ U* ^. g( c
- R t# `3 s# \& x+ _$ @1 z& a: i5 X8 m* e1 k
' z, D' A) v1 T* ]8 w! \
" o' l5 z# ~8 f * |5 H+ K! d+ P
" e5 ^7 g/ D4 W7 u- Y2 O& |* C
expression=“execution(* com.javakc.aop.MyTarget.t*())”/>' Z" E* B; S# X' o
$ Q7 X4 E) Y1 Y( u# s! X4 F
6 }9 M% y5 K9 i) O: u7 N4 R, x9 V 0 }- U* q) n% [' k- K9 h; [
D/ b/ Q" r, Q7 I
" ?& |# u, K0 c( h5 n% I" s
5.3.使用注解的方法相对简单
& X) D5 @; g2 A+ L @AspectJ的基本语法& o9 b8 |0 y: S3 V$ [
1.@Aspect声明一个切面,将一系列的共同的功能定义成一个切面
( Y4 |) L8 `3 Q7 W5 F5 x 直接在类上定义@Aspect r# Z9 L% d8 t7 m6 w
2.@Pointcut声明切入点
$ n" }6 V8 A: o9 a/ @ 2.1、用一个专门的类来定义pointcut,类中的方法名就是该pointcut的名字
* W: g& |" G" \" f$ y2 ? 2.2、可以使用匿名的pointcut
% {1 W" d2 L$ u% f& [ 2.3、执行切点的几种方法
; ?5 v( V( D5 R/ P0 r 2.3.1 execute(public * 包结构.*.*.(..)) 可以指定到具体的方法
7 W& ]$ B7 ]4 {+ \ 2.3.2 within 指定到包,不能指定到类
/ W* l0 v. P" O; L, y9 _ within(”com.javakc.spring..*”)
6 W% F1 H* l+ [8 z/ ] 2.3.3 this 指定到实现接口的所有的实现类
8 L% s: H6 S/ [' S5 h4 b0 M 2.3.4 target 指定具体的实现类/ W& T& s+ [9 U+ s; @
5.4.advice的五种类型的示例* |* {. W5 Q9 m* S u: J
客户端必须从接口走才能得到监控,实现想要追加的功能2 {5 a; h- b8 n
5.4.1.@AfterReturning(pointcut=”” returning=”retVal”)
/ z7 `. |0 Z, ^/ X5 H 追加的方法的参数名字一定要与retrning的名字相同
& `, ~+ {* V" y) }5 T* e 在注解@AfterReturning中必须加上pointcut和returning两个参数, l9 p. c, z+ H/ \/ I0 q4 \3 |
pointcut指所要监控的目标对象的方法: ?: i" N! z( X* v* w4 S
得到目标对象的方法的返回值,来作为参数,进行下一步的处理,参数没有顺序,按参数的名字进行匹配# \0 i$ ]# e5 P- A) W" E g
完成追加的功能4 O: b, C) F# z% Z' ~) \
1 定义一个pointcut,通过方法名来作为pointcut的名称来引用" k- a4 `: o, h$ R: j
(1).@AfterReturning(“com.javakc.spring.schemaaop.TestPointcut.t4()”)4 ?, q& J8 b8 u9 ]6 x2 y! Y- Z
(2).; ]. z/ h% q8 H6 ?
2.直接引用匿名的pointcut
: f5 {2 |. w; ^ N/ J1 x5 X! ]- t& E (1).@AfterReturning(“execution(2 r7 f3 q7 Z. \3 Y4 [; |3 Y
* com.javakc.spring.schemaaop.Api.test4())”)
. v. G V8 J, @ (2).@AfterReturning(pointcut=, `2 ~5 B) `( Q8 h7 q6 n; U
“com.javakc.spring.schemaaop.TestPointcut.t4() &&
# ]4 C, }3 ~* ]. L3 o" d args(str)”, returning=”retVal”)1 y. o4 P3 c% U' N
@AfterReturning (pointcut=”com.javakc.spring.schemaaop.TestPointcut.t4() && args(str)”,returning=”retVal”)
+ ~9 J/ x3 z# s$ e( H0 ]& ]3 C! V public void testAfterReturning(String str,Object retVal){2 H* `7 G$ T* M x
System.out.println(“afterReturning1=>”+retVal+”=>”+str);
1 B, b/ o* b9 J" D) \ }7 X; u9 c b0 v
5.4.2.@Aronud
p& ^7 f% ^) u 注解@Around环绕追加功能;
) j3 |6 j9 K1 b 在执行目标对象的方法的前、后追加功能;& f3 e0 c3 ]& ]+ ~9 v" i
必须有参数;第一个参数的类型必须为ProceedingJoinPoint;* r' y" I9 T, ?1 C
通过ProceedingJoinPoint的实例的proceed来调用所监控的1 [2 P2 q s2 q: G/ R: K
目标对象的方法
9 q% ~/ [7 _( O% H! R$ ` 1 定义一个pointcut,通过方法名来作为pointcut的名称来引用
' T* K" A6 V8 ^8 ~" j (1).@Around(“com.javakc.spring.schemaaop.TestPointcut.t1()”): ~- ~. T# i0 i* `
(2).@Around(“com.javakc.spring.schemaaop.TestPointcut.t2()
2 C+ f: c4 ^3 c5 b+ o8 \ && args(str)”)
1 S$ |$ C3 }8 X7 ]5 y% _ 2.直接引用匿名的pointcut
9 a: W5 Y+ w- a2 I (1).@Around(“execution(
# l3 Y7 \; ?0 R3 O7 _9 a: O) H * com.javakc.spring.schemaaop.Api.test1())”) i$ ^8 [( j0 I* P' h
(2).@Around(“execution(* L0 y$ I( G5 P7 l( F8 U& Y. e0 D6 _
* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)3 X$ l/ d+ B# a7 z
// @Around(“com.javakc.spring.schemaaop.TestPointcut.t2() && args(str)”)
% A, q) S6 Y1 [5 L6 C L) p6 f: I @Around(“execution(* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)
: }( b2 Z% }' Y4 C% L7 G; z public void testAround(ProceedingJoinPoint prj,String str) throws Throwable{8 J. d( Q) \- `. c7 r2 W- ~1 y. c
System.out.println(“around1==========before1pointcut==>”+str)' L5 ?3 P2 n( \2 ^9 b4 J5 D
Object obj = prj.proceed();+ G. J3 z4 H z, @- j9 ^
System.out.println(“around1==========after1pointcut==>”+str);
& C5 y0 O' l X ^0 E# N; m" Y }
6 D- M: Q. e ?; F0 t 5.4.3.@Before) _. k. S3 u1 ~% X2 V
注解@Before在执行目标对象的方法前追加相应的功能$ p/ J6 R M. Y- {& z6 _! m' L+ `
1 定义一个pointcut,通过方法名来作为pointcut的名称来引用
+ }. [) R5 Y4 C/ r7 ^, _ (1).@Before(“com.javakc.spring.schemaaop.TestPointcut.t1()”)
+ { S# ^6 H2 [+ f+ Q9 f* ^# \ (2).@Before(“com.javakc.spring.schemaaop.TestPointcut.t2() && args(str)”)
6 r. ]& A, E# |, a) J 注意args后的名称与参数名相同, V3 ?- F+ n/ v8 D V
2.直接引用匿名的pointcut
6 T: V8 }1 Q( L9 v (1).@Before(“execution(* com.javakc.spring.schemaaop.Api.test1())”)3 p Z8 r; O( c. c+ k* b5 n
(2).@Before(“execution(* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)( Z- O' e5 D* l0 j5 F0 h
注意args后的名称与参数名相同( T4 a0 u! Q) W1 H) K3 J/ `
// @Before(“com.javakc.spring.schemaaop.TestPointcut.t2() && args(str)”)
* V) S" |/ Z1 w @Before(“execution(* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)
! t1 b1 W7 `8 v+ R- z3 Z) L public void testBeforeParam(String str){
7 t& D8 D4 E2 X6 ^" ~# b X3 e System.out.println(“before1=param=>”+str);- H! r1 U9 P& g, g
}; h; U7 A3 ? H7 m* Q* |: X- T
7 f! r3 u: o! G% r1 M5.4.4.@After2 V! ?1 D9 M+ r
注解@After在执行目标对象的方法后追加相应的功能$ U, h8 `# @, U/ p8 q
1 定义一个pointcut,通过方法名来作为pointcut的名称来引用+ K6 f. B! X9 v! U" V+ J
(1).@After(“com.javakc.spring.schemaaop.TestPointcut.t1()”)& h* y1 S7 c) ~6 \, `' o+ b
2.直接引用匿名的pointcut
$ r& m$ }: G0 ]3 d4 ` (1).@After(“execution(* com.javakc.spring.schemaaop.Api.test1())”)% u' ]- H5 E( }" K' E' c
@After(“com.javakc.spring.schemaaop.TestPointcut.t1()”)
: v* }3 f) S; t2 k/ Z" W public void testAfter(){
8 b' K9 P i" Y System.out.println(“after1== >pointcut”);
' \$ v7 v+ }7 E7 [% _ Y }
& e4 `* X6 I+ C2 g6 e 5.4.5.@AfterThorwing
8 N+ [# G6 M) `1 o2 \
% j; B& ]9 Z+ {2 W) @ N, z: a2 z4 `8 c' g/ e: W
- 描述一下spring中BeanFactory和ApplicationContext的差别
( \! U+ A" H* R+ J. s. d3 s% {
( `" ]" n- b, T2 |+ f) b% |
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/ j! x' V1 ?% X7 A- 谈谈spring对DAO的支持
4 A0 F/ m# L/ c, t( f
+ k# a# E, H% ?4 [7 o# A: F
Spring提供的DAO(数据访问对象)支持主要的目的是便于以标准的方式使用不同的数据访问技术。
/ G& t, Q/ v- W* F2 r+ b* g 简化 DAO 组件的开发。- x' A; H- O) m- n% ~5 W6 z
Spring提供了一套抽象DAO类供你扩展。这些抽象类提供了一些方法,用来简化代码开发。* H" A) k5 o) q* m1 ^' }; W
IoC 容器的使用,提供了 DAO 组件与业务逻辑组件之间的解耦。所有的 DAO 组件,都由容器负责注入到业务逻辑组件中,其业务组件无须关心 DAO 组件的实现。. ~( m6 E) j# q: `$ _8 S% o, d
面向接口编程及 DAO 模式的使用,提高了系统组件之间的解耦,降低了系统重构的成本。& c6 ], w6 j2 Y+ L9 n& s g
方便的事务管理: Spring的声明式事务管理力度是方法级。
$ G2 _# C( i* T3 t; [ 异常包装:Spring能够包装Hibernate异常,把它们从CheckedException变为RuntimeException; 开发者可选择在恰当的层处理数据中不可恢复的异常,从而避免烦琐的 catch/throw 及异常声明。
: n! _) w4 S: H3 M9 _
( j" _; t+ Q6 ^9 r) |' C
( C! h4 o9 o8 e$ i- 谈谈spring对hibernate的支持
: X3 W. l, q4 f6 |* j5 M
7 k: P3 j' S7 e* ^9 Q& V
在所有的 ORM 框架中, Sping 对 Hibernate 的支持最好。如 SessionFactory 的注入、HibernateTemplate 的简化操作及 DAO 支持等。另外, Spring 还提供了统一的异常体系及声明式事务管理等。9 k6 p' B$ x- k* @5 x
一旦 Hibernate 处于 Spring 的管理下, Hibernate 所需要的基础资源,都由 Spring 提供注入。Hibernate 创建 SessionFactory 必需的 DataSource ,执行持久化必需的 Session 及持久层访问必需的事务控制等,这些原本必须通过代码控制的逻辑,都将由Spring 接管 ataSource, SessionFactory, TransactionManager等,都将作为 Spring 容器中的 bean。将这些bean 放在配置文件中管理。
7 m! s2 W" C5 u5 y9 `$ P% m 1、通用的资源管理: Spring 的 ApplicationContext 能管理 SessionFactory,使得配置值很容易被管理和修改,无须使用Hibernate 的配置文件。详细配置如下:# Q- V6 h# j* L7 X t: b" r
/ r$ d9 Y% u c2 Y* F( ]9 ]
class=“org.apache.commons.dbcp.BasicDataSource”>: p+ _) ?/ C- M( f! F
) U z9 G$ i' g% S' c: Q
oracle.jdbc.driver.OracleDriver6 K2 [& z3 Y4 j1 T& d
; {0 Q4 |0 r9 [( |) b( \
( T& J+ Z) G7 X jdbc racle:thin localhost:1521 rcl- m& W# w" p* T+ Q. | X* ^# L
8 \; E0 L. {: f. ]
/ q* M: |, p5 H- a1 w+ u; z javakc2
$ G3 P, n! d% N1 c3 P + g: ^# R, P# m% o7 |9 S
2 ~9 ~( |6 h U% j( f! c
javakc2
9 \# B9 i; K" \7 m6 f2 W% u 7 t2 V* W+ P, p5 G
2 b5 s0 d- n% K
! ~% Z1 u# J7 g }) Y class=“org.springframework.orm.hibernate3.LocalSessionFactoryBean”>" H, u5 o& z! z& V$ Q
# [( e2 C) v" V' ~
4 y% |6 J0 S4 |# L! F
' E8 X/ x3 c I, T* g/ I com/javakc/spring/h3/UserModel.hbm.xml# L- e4 m' I/ c! K0 _
0 @, R( o9 `" I3 `
# c0 ?% Q" G$ k+ k; f% A
! o% F- n# J+ Y- E t
- v- ?+ o& B5 y& w( `1 G0 V
hibernate.dialect=org.hibernate.dialect.OracleDialect1 h0 j3 i$ s( |! J
. \: _, R& | Z7 X f9 U8 V) ]: T/ \, H
: K1 W8 L5 S' ?7 d* l8 { 4 l2 C0 Q, S6 Q/ r4 J. u
2 s# g3 G$ ~: x; l& e1 t* g8 z
! P( X) U! O# h4 c1 W# X 如果需要使用容器管理的数据源,则无须提供数据驱动等信息,只需要提供数据源的JNDI 即可。对上文的SessionFactory只需将dataSource的配置替换成 JNDI 数据源,并将原有的 myDataSource Bean 替换成如下所示: class=“org.springframework.jndi.JndiObjectFactoryBean”>* M; a3 \1 P% j: ]' _2 o
3 _2 F7 U ~4 h2 M java:comp/env/jdbc/myds
- c; V5 I# ~. I* b+ t0 p
8 V" Y% {. L( Z/ O% W4 j# g* n 2、有效的 Session 管理: Dao类继承HibernateDaoSurport后,Spring 提供了 HibernateTemplate,用于持久层访问,该模板类无须显示打开 Session及关闭 Session。它只要获得 SessionFactory 的引用,将可以智能打开 Session,并在持久化访问结束后关闭 Session ,程序开发只需完成持久层逻辑,通用的操作则由HibernateTemplate 完成。 3、统一的事务管理。无论是编程式事务,还是声明式事务, Spring 都提供一致的编程模型,无须烦琐的开始事务、显式提交及回滚。 建议使用声明式事务管理,Spring 的声明式事务以 Spring 的 AOP 为基础。可将事务管理逻辑与代码分离。代码中无须实现任何事务逻辑,程序开发者可以更专注于业务逻辑的实现。声明式事务不与任何事务策略藕合,采用声明式事务可以方便地在全局事务和局部事务之间切换。 Spring声明性事务有两种配置方法,一种是xml配置:
9 D d: ^( T' W; O4 U& U
6 F5 ~9 G8 }+ H1 }* `
$ b: a6 b$ U3 }) v- Q ; J: e/ A3 R, E! w8 E
% r2 w. {% \# P' b [
3 c/ h: K0 h2 {9 b0 W! n P J' o1 b0 m+ |& w
3 r7 f2 ]2 i( j% o Z
1 [. W4 L' r: F+ m6 T * a9 P- o# K7 i8 q1 H
! a) C, V5 m4 b- F7 L$ w" r7 u
( Y# F2 h/ f: y$ m% i5 x
2 e S/ U; k: g2 C& z
8 b0 b; s8 ^' ^ 另一种是通过注解,在需要添加事务的类上注明 @Transactional
& V0 Q; e# Q* o5 @Spring2.0之前事务的写法0 C6 p0 W3 n/ b3 d. h# p
) i1 u, m$ l; t
2 b7 _) S( W; Y9 G' @. G class=”org.springframework.transaction.interceptor.TransactionProxyFactoryBean”
) R4 @+ c9 w0 U1 t$ y$ z F
% A& H3 J; h7 y: `0 S abstract=”true”>
2 c V# n, W# J8 C) j3 [
/ P: W" n& N5 c4 |: a
9 ^5 [0 `4 I& ]7 }2 w
& Q u, N5 T- z( w+ F
@8 W! s4 V! ^( r( ]. u' Y PROPAGATION_REQUIRED,readOnly; d( }$ v% b8 Y% p( n( U7 q
( ?( c0 Q% z4 `. P
PROPAGATION_REQUIRED
, W% f; @: r5 t* |. O' e- C
; H: `7 P, a% k+ k
: }' ?2 {# o$ W% v, m4 ]* e- i& `+ u, O& H* l3 d
( x5 S3 f G+ N4 W9 j8 J c
| 8 \% A) I, C: W3 ]
+ i8 S9 ?. r; @# v
- 谈谈Spring对事务的支持
+ K8 x" h. k: B
9 {8 {" B; B. z/ Y
- l$ N3 K4 F% t) T1 @3 f) A I! {
1、声明式事务管理: 1.流程:由客户端访问—-aop监控—-调用advice来追加事务 2.做法: 2.1 在配置文件的头中引入xmlns:tx 和schema的文件 2.2 2.3 注入数据源
+ w" g w# {. U2 R0 ?5 K" H
' X0 B% y3 t3 e, z+ U6 V n" f* c- o# }/ {0 X' f
2 {" [* T& z, C4 ?4 B* S6 q# M, `7 [! Y3 J9 _
0 C2 ^ e; m) |# O5 Q/ M$ M2.4 由spring实现的事务管理,但需要注入数据源
- G/ _+ o* Q2 L
& h8 e. Z6 e5 Z9 s
$ w, _, }+ z' }5 y3 |2.5 事务监控所有的方法(事务加强) m, s! }" j9 P7 ]
6 N% [# L6 I! G3 g6 Q9 k' |" ]
0 A. e- ~" V) {- Y }, d1 m
# H/ v( ^ {* t8 o, |
; w" s+ q/ y3 o2.6 定义切入点
) W/ C! J0 ]) n7 x Y' w$ @
: ` u2 J4 C- [, ~
1 y7 W, V) _; ^% t' j* D. u+ z# D3 ~. C0 V" \( D6 v& ~5 f
. Q% S% q8 N3 R3 l K/ y$ i$ r2、使用注解实现事务管理: 1.注解@Transcational (可以在类上,也可以在方法上) 2.在配置文件中同样需要注入dataSource和spring的事务管理 3.使用注解的方法来追加事务 注解驱动
5 U& G) }" P! M
3 R* g+ K3 j% N( C: w4 B如何在Spring中使用Hibernate的事务:& _0 `- R" M+ C& ]
$ Y: N7 K1 x( D( m
a2 {4 t, y* v' C) a3 l) \ ; W) i$ c* j {" n- O& k+ Q
如何在Spring中使用JTA的事务:
- L9 I! y: m1 F7 C: K7 n. ?- Z
" u! \- j% w3 a' R2 U; L |