Spring$ O% w9 A% @6 c3 ]& Y
- 是什么? o: b; @; |, e. H) _1 |
1 I4 C1 _4 z( n; k
Spring是基于JEE的轻量级的应用框架 1 N6 Y4 r$ Z5 R: @0 S
- 有什么?
; ]+ z+ q) h. P% `5 r8 ?; x7 j9 u: T& X+ x) d/ b
" L3 w5 G! ]2 `- O7 |1 h$ ^
每个包的功能: Spring MVC:spring 本身提供的web 框架 WEB:集成其他的web 应用的框架,或者说是对其他web应用框架的支持。如struts,webwork JEE :集成一系列的jee的技术(对JEE技术的支持) DAO:封装了JDBC;(对JDBC的支持) ORM:提供了对ORM工具的集成(支持) AOP :面向切面编成 CORE:spring的核心包,提供bean的工厂和IOC容器
; J; c" x; ^6 C- 能干什么?7 q/ [4 p W8 S$ N% a4 Y
+ Z4 V, k! H6 N' q
把一系列的jee的技术有效的组合在一起形成以良好的系统 . G4 H: F4 O& q2 k, c" A
- 怎么用?
" u- V/ j; k }% b/ ]$ M: z) {; ?( G( j! [$ f2 y
- 搭建web工程,引入spring的jar包4 a Q5 Y- k2 p0 {
- 在web.xml中添加如下配置
+ G. a g/ ?" W! I, O; S
5 {0 m: k4 k6 e# m5 U; n / |0 R# V7 N( ^1 h0 t
$ k" \( Z3 X0 ?* P7 y% I Y& j. {
contextConfigLocation0 s7 [8 H2 p2 ~6 p$ N$ C/ O" W& D
classpath*:applicationContext*.xml
4 u* E7 U9 @- P ! S! P5 k9 }6 D$ r5 X/ R
n7 g! y6 r) F8 \5 z; r; ^
struts2
" {6 ^! X$ w. S/ ~ U 7 V- D$ @) e' F: G- |) Z4 ~: ]& k; K
org.apache.struts2.dispatcher.FilterDispatcher- F. k1 s+ U1 W2 g0 s
+ b+ J$ V5 A3 l 4 S0 q6 Y# f7 _; q* Z4 R J4 a
3 a, P- ]& I8 ?7 J
struts25 a V, x+ Z8 A- }! i4 b4 s* a( `
/*
B4 s# c+ z; v( p. \ 5 V) H9 A% ], n1 v& y$ n5 d+ B: a
: [5 R- t! N3 M( J. e
) A& s: |8 g: F/ b `
org.springframework.web.context.ContextLoaderListener, s7 f- y# ]: z0 c0 D
! _$ ]* F3 A9 s* U5 V* V
- 部署: c; U: P2 {* n. O: f
/ ^9 o0 R0 w* s4 ]1 W
& [4 S8 L; C! k2 N
. [; a+ `) Y# Q# A- H# d" W
+ Y1 g+ T: v7 w% _; n* V& d- 容器和bean
! H1 @" z) e5 _% ~& n, R
Bean :是指受spring的ioc管理的对象称为bean 容器 :(与jee的容器类比) Jee :提供组件的运行环境和管理组件的生命周期(不能单独存在) Spring :提供bean的运行环境和管理bean的生命周期(可以单独存在)
% j, }3 U5 g1 I# a2 ?- u. C3 u+ Z1 h/ j" t' z
- DI依赖注入
0 Z) j- y1 J3 d" a2 w
1. 应用程序依赖spring注入所需要的对象 IOC和DI是对同一种事情的不同描述 2.setter注入: 在配置文件中将接口的实现配置为bean在应用程序中注入bean 例如: 在配置文件中 & P2 O% u2 |' q) w
/ t7 } ]* ~& f% x% F8 N
8 Y# b( t7 V+ F/ x在应用程序中 Public DBDAO dao ; Public void setDao(DBDAO dao){ This.dao = dao; } 3.构造器注入 2 [/ k$ }' `4 B, l( o
4.ref 表示参照其它的bean 在参照的过程中一定要注意死循环 5.自动装配———–〉no 自动装配根据名字来匹配相应的bean 尽量不要去自动装配 6.lookup注入 7.singleton 1.单例模式是整个的jvm中只有一个实例 2.spring的singleton是指在spring的容器中只有一个实例 一个生命周期中只有一个实例 8.DI的优点: 1.程序被动等待,强化面向接口编成 2.切断了对象或组件之间的联系,使程序的结构更加松散,运行和维护更加简单 # ~* M, Y2 H0 k4 Y# @) Q0 S, O
- Aop面向切面编程
5 c3 K' J7 I* [6 d( B- O4 M, p ~& I- ~5 V: V3 v4 f
1.AOP面向切面编程 一些较好的模式或者是示例—-范式
4 S" r* N8 L {! w 切面:一个切面代表我们所关注的一系列的共同的功能点(模块之间的共同的功能点) 2.AOP的思想: 主动—->被动(追加功能). Q; ~$ C6 I" J' p ?* H3 n$ M
3.AOP 的概念
8 n& U) i! t4 P1 h" i# L/ X' O 1.切面 :我们所关注的功能点 2.连接点 :事件的触发点(方法的执行) 3.通知 :连接点触发时执行的动作(方法) 4.切入点 :一系列的连接点的集合 (连接点的模块化) 5.引入 :扩展的功能 6.目标对象 :包含连接点的对象 7.aop代理 :实现机制 8.织入 :把advice和目标对象连接起来 4.AOP的事件机制
q) a: u3 D C0 s! w+ D 1.通过切面找出一系列共同的功能点 2.找到目标对象(在标准的spring 中 接口的实现类为target) 3.找到切入点 4.确定连接点 5.通知spring AOP,查询xml文件,通过代理找到advice。 6.由aop代理来实现动态织入
+ d% r! E, D) q# \7 | q, p$ ? [$ {4 d" i1 s: w6 J
% X: j1 I9 A$ o- y
$ w& P. _0 @% P( d5 {" y6 y, y# f
X q: C K% ~" v5 ]
2 @" x" T3 B3 ]0 s/ q; [ Y
5 `3 `5 p* `3 h0 g. G5. AspectJ+ \$ [. g6 P( k" O# f
5.1.在xml中配置比较烦琐
! }5 G0 n9 |7 M* \( }( r' S 所有的入口必须从一个代理(ProxyFactoryBean)开始
4 ~' [& s" O, @/ ?# o m " j6 G5 C" N3 T$ {. u3 T
; m% E5 ~* V$ A$ x4 E7 t) _1 t/ a
% f" p' o% q7 J8 z( g+ |: ^+ m
. y0 G8 E3 @$ v& k# b/ @- |0 f
( g, Q; j$ H! V! |& I
' t* l5 V: n* D8 H
! F; G0 M9 b" H8 b; A; C, z 9 i) M( @6 Z2 d
expression=“execution(* com.javakc.aop.MyTarget.t*())”/>, ~, V5 J3 x; T6 j
5 ~# Q7 _8 P* d% U) ]( B
/ l% _% @* C( m& n
0 J$ C1 ^% ?) k2 @
O/ B8 h0 ~! e
% J- R3 x' j+ }% T7 m* O: t5.3.使用注解的方法相对简单
; [. R: c7 D' b, b- P @AspectJ的基本语法
( j4 [% J- n$ d" ~$ C5 F2 A! s 1.@Aspect声明一个切面,将一系列的共同的功能定义成一个切面
$ y: K$ x$ H; ?, m& p 直接在类上定义@Aspect
7 c" _2 E1 d$ w; v 2.@Pointcut声明切入点
( a/ ~% ]5 [/ I- r8 Y 2.1、用一个专门的类来定义pointcut,类中的方法名就是该pointcut的名字
# C% s/ ^4 g) z& Z 2.2、可以使用匿名的pointcut3 w8 b( V; _9 H2 f/ F
2.3、执行切点的几种方法
3 {' m+ I3 p* x1 E 2.3.1 execute(public * 包结构.*.*.(..)) 可以指定到具体的方法
! z1 O+ z2 W" e4 A" b1 u( _3 Q" \ 2.3.2 within 指定到包,不能指定到类
7 w0 f1 Q1 v# T3 d" A within(”com.javakc.spring..*”)/ v/ Z2 x% @. `$ {+ w% y/ {: E
2.3.3 this 指定到实现接口的所有的实现类
: }3 d5 K V$ o- f1 d 2.3.4 target 指定具体的实现类
1 K/ R W( D: O 5.4.advice的五种类型的示例( K; t) E- Y; V( p# E- t5 W+ ^
客户端必须从接口走才能得到监控,实现想要追加的功能3 Y1 |$ M: g! }5 H
5.4.1.@AfterReturning(pointcut=”” returning=”retVal”)& Z$ W! ]; d7 P
追加的方法的参数名字一定要与retrning的名字相同% Y5 R. w, |) v1 {$ M5 c7 c
在注解@AfterReturning中必须加上pointcut和returning两个参数: r9 K% A7 t5 g) E
pointcut指所要监控的目标对象的方法; P; J6 |8 U$ G0 e( a
得到目标对象的方法的返回值,来作为参数,进行下一步的处理,参数没有顺序,按参数的名字进行匹配
- [$ i* r; x# c8 _' p% t 完成追加的功能6 Z6 q7 m0 x& S' R5 B
1 定义一个pointcut,通过方法名来作为pointcut的名称来引用
3 x% f) r6 G# O9 R (1).@AfterReturning(“com.javakc.spring.schemaaop.TestPointcut.t4()”)
, l" T0 O$ H9 w7 B: e% x1 q (2).
6 i& u, e& y3 Y/ z# m 2.直接引用匿名的pointcut
# ?8 j$ I9 }# w2 q7 U }" w# ^0 _ (1).@AfterReturning(“execution(
5 [5 B' [7 ]! H4 X4 n F * com.javakc.spring.schemaaop.Api.test4())”), B3 f* v' U/ s4 ~
(2).@AfterReturning(pointcut=. ]% L- a" G. f! M1 D/ s" O+ R
“com.javakc.spring.schemaaop.TestPointcut.t4() &&- W) J$ G! v4 y4 s
args(str)”, returning=”retVal”)
6 `& z( y! l4 {4 \! V) Q; O @AfterReturning (pointcut=”com.javakc.spring.schemaaop.TestPointcut.t4() && args(str)”,returning=”retVal”)
( A! p0 `& i9 |4 U public void testAfterReturning(String str,Object retVal){
2 `5 W) a4 @0 |* K' T System.out.println(“afterReturning1=>”+retVal+”=>”+str);/ y/ A5 R' p9 w% X
}+ {$ L3 s [6 I3 n4 V
5.4.2.@Aronud
% l2 Z7 ?6 N; `2 E 注解@Around环绕追加功能;
- L3 S% L5 f* `2 Y2 V 在执行目标对象的方法的前、后追加功能;
3 h5 i$ |4 q9 v' N! j5 N3 r" Q 必须有参数;第一个参数的类型必须为ProceedingJoinPoint;" n: g# w3 _* ?0 e- T
通过ProceedingJoinPoint的实例的proceed来调用所监控的8 i, l3 u7 R, |, u1 x
目标对象的方法 o7 l+ E' M8 i
1 定义一个pointcut,通过方法名来作为pointcut的名称来引用" Q$ a$ }% q" u8 j
(1).@Around(“com.javakc.spring.schemaaop.TestPointcut.t1()”)3 l4 t$ l) E j. s" R1 r# d/ X2 O
(2).@Around(“com.javakc.spring.schemaaop.TestPointcut.t2()
( a& P/ r% `. |: t. n && args(str)”)0 l# c. ?8 K7 s* s% u# z
2.直接引用匿名的pointcut
, s7 q+ E/ k: p* _5 r* ]& B* Q (1).@Around(“execution(
) }" I' }9 ?/ U c w" p, E * com.javakc.spring.schemaaop.Api.test1())”)
2 V# F# Z( N8 Z" z; n2 [/ C7 f (2).@Around(“execution(
6 L8 y$ A( U) ~2 j6 J * com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)) w3 E& ]& P# i' A: x: @
// @Around(“com.javakc.spring.schemaaop.TestPointcut.t2() && args(str)”)
# A0 e- F3 A2 J) c) r6 O2 R @Around(“execution(* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)& }5 i0 ~" W- `) Z8 W
public void testAround(ProceedingJoinPoint prj,String str) throws Throwable{
( F! ~$ @$ a6 Y9 F% F H+ x System.out.println(“around1==========before1pointcut==>”+str)# ]" ~ S1 t* u& D# p, [% a
Object obj = prj.proceed();' g2 n7 {0 L$ a2 ?5 R6 g+ M
System.out.println(“around1==========after1pointcut==>”+str);
0 r* g0 f/ e$ d, q( o# e; A3 Q3 A* y5 n }$ l3 @% D' `4 N- M. H
5.4.3.@Before
# @% [/ u% D0 p: J. w2 q 注解@Before在执行目标对象的方法前追加相应的功能
) s* [, P$ I9 m4 n 1 定义一个pointcut,通过方法名来作为pointcut的名称来引用
# ~( g; ~- v1 T3 j (1).@Before(“com.javakc.spring.schemaaop.TestPointcut.t1()”)3 {0 G/ n C: X' E: r* o+ D, [
(2).@Before(“com.javakc.spring.schemaaop.TestPointcut.t2() && args(str)”)4 Y% p& E4 i1 z
注意args后的名称与参数名相同
' I! {9 M& \7 s% N, l( `" K4 g( S7 ~ 2.直接引用匿名的pointcut# W0 t6 t0 i6 h/ u9 p; f$ i
(1).@Before(“execution(* com.javakc.spring.schemaaop.Api.test1())”)
2 a) `( o2 B9 [: H (2).@Before(“execution(* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)
3 d% h+ D5 z8 ] 注意args后的名称与参数名相同, N/ D' l2 \5 T4 H/ U$ ^4 g
// @Before(“com.javakc.spring.schemaaop.TestPointcut.t2() && args(str)”)" h: b* M) N7 q+ S* U
@Before(“execution(* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)# R( Q8 a! G8 n" @- W6 B4 Q1 p
public void testBeforeParam(String str){, k- Y2 G( [4 Z3 S4 S: J
System.out.println(“before1=param=>”+str); R7 d6 ]6 J8 N8 a% q
}( a" u/ W. L2 e9 o/ n
- H, ~% b; H: k( |% `9 e o
5.4.4.@After4 R3 H- U% S. D! c b# L
注解@After在执行目标对象的方法后追加相应的功能7 C" ]4 d7 C4 X2 {/ b% H# I
1 定义一个pointcut,通过方法名来作为pointcut的名称来引用
, V2 Y. W& ^4 e6 K, R7 S (1).@After(“com.javakc.spring.schemaaop.TestPointcut.t1()”)" i' L& w- [' n3 n& u" |
2.直接引用匿名的pointcut
& m# Z: W* p- ?& ? (1).@After(“execution(* com.javakc.spring.schemaaop.Api.test1())”)
! B# K7 w* w, l5 l0 v" v4 O2 p @After(“com.javakc.spring.schemaaop.TestPointcut.t1()”)
# q; u5 {+ Q% Q public void testAfter(){
1 @5 E5 x. c: f- U2 a, [) |9 F System.out.println(“after1== >pointcut”);
- |! f* D7 M9 P" H: ]) N }- T; j0 v$ @ _7 N; x6 t) C. \9 H
5.4.5.@AfterThorwing
9 M! {& u; R4 o G& v . p- o- X l8 X0 o, c
4 j* F+ M, i# h' H0 d6 K: F
- 描述一下spring中BeanFactory和ApplicationContext的差别
4 F H9 B5 S& |5 G1 z0 [4 e! o4 b
, `1 i! {; z! B) c# [5 e2 ?
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”);
! _; G2 s( a2 q5 B- 谈谈spring对DAO的支持# L: M6 o8 R0 f3 q3 c0 ]
3 ^2 o; l% |- }) R* ]6 E- [
Spring提供的DAO(数据访问对象)支持主要的目的是便于以标准的方式使用不同的数据访问技术。
5 P2 }: L+ ]4 K$ y 简化 DAO 组件的开发。
' Y3 R2 {2 e2 v9 SSpring提供了一套抽象DAO类供你扩展。这些抽象类提供了一些方法,用来简化代码开发。0 F+ a. G: k, S4 d# K
IoC 容器的使用,提供了 DAO 组件与业务逻辑组件之间的解耦。所有的 DAO 组件,都由容器负责注入到业务逻辑组件中,其业务组件无须关心 DAO 组件的实现。+ N ?: s% R; O2 M. l6 [, L
面向接口编程及 DAO 模式的使用,提高了系统组件之间的解耦,降低了系统重构的成本。
5 _( H# u3 }( I$ d$ M! I. a 方便的事务管理: Spring的声明式事务管理力度是方法级。# `% P# R* n1 s2 {
异常包装:Spring能够包装Hibernate异常,把它们从CheckedException变为RuntimeException; 开发者可选择在恰当的层处理数据中不可恢复的异常,从而避免烦琐的 catch/throw 及异常声明。
+ `& u$ n$ w7 t2 q' u4 j 2 X6 e f# r! [
1 P/ T2 t: {2 L# B/ p) Y+ N3 H
- 谈谈spring对hibernate的支持
9 y4 j% w( |/ G
- r+ s, ~# M( l4 r8 N
在所有的 ORM 框架中, Sping 对 Hibernate 的支持最好。如 SessionFactory 的注入、HibernateTemplate 的简化操作及 DAO 支持等。另外, Spring 还提供了统一的异常体系及声明式事务管理等。
, ?8 E* d7 Q' b# } ?) { 一旦 Hibernate 处于 Spring 的管理下, Hibernate 所需要的基础资源,都由 Spring 提供注入。Hibernate 创建 SessionFactory 必需的 DataSource ,执行持久化必需的 Session 及持久层访问必需的事务控制等,这些原本必须通过代码控制的逻辑,都将由Spring 接管ataSource, SessionFactory, TransactionManager等,都将作为 Spring 容器中的 bean。将这些bean 放在配置文件中管理。1 m! o# Z7 b9 ^* \
1、通用的资源管理: Spring 的 ApplicationContext 能管理 SessionFactory,使得配置值很容易被管理和修改,无须使用Hibernate 的配置文件。详细配置如下:# A9 J& `& r$ N
9 M! a* s* j3 } A( m1 s/ o class=“org.apache.commons.dbcp.BasicDataSource”>
+ H- n+ i, `/ i5 G: g$ Y* F
. p5 s# W4 b( a6 @ oracle.jdbc.driver.OracleDriver7 O, W4 |, K4 K; d; t9 K4 @/ i
+ f) K5 N& x b6 J
1 R4 `0 o6 r/ p7 F0 S
jdbcracle:thinlocalhost:1521rcl
2 Y S9 B5 w% L4 |' j : Z- L. o% p5 I- a, o' O8 d
# e$ ^. Y0 I" ] javakc2
0 X4 |7 A4 s F1 w* ^ 9 z, p/ H. U4 S; v7 \7 P
0 m; R# z4 x: m5 N: U javakc2
+ R8 N4 g9 h1 Y * M8 l1 a( F5 O2 u1 K
* D( L6 w% p. d7 {6 c0 W
6 G& S- i' m! O3 J class=“org.springframework.orm.hibernate3.LocalSessionFactoryBean”>
j5 t \" q9 L
' ~6 N7 `$ x$ Q3 i. K: I4 E / D8 e5 T; q0 M
. G! v& ]8 q$ G% z! T5 A$ D
com/javakc/spring/h3/UserModel.hbm.xml
0 n2 G: ~4 R8 E
$ h" F% n+ r" {# b2 d2 N
- ]" {7 ~. v: h* Z9 Q ( K/ Y/ M* q( x* t
, N/ [9 G8 F/ K: d) D6 @( u hibernate.dialect=org.hibernate.dialect.OracleDialect
% _6 E8 m; O: M1 m/ h% ] 7 N7 R6 B% Z! y" B8 I2 T, y
/ } {3 S8 ^8 X( Y
/ A& Q+ C5 n7 `# a# r1 ` . ]2 S8 K+ o) _, D. { P9 }% U4 W+ k
3 v! P7 \! E* k( B
) V# t! j8 P5 d, H9 g
如果需要使用容器管理的数据源,则无须提供数据驱动等信息,只需要提供数据源的JNDI 即可。对上文的SessionFactory只需将dataSource的配置替换成 JNDI 数据源,并将原有的 myDataSource Bean 替换成如下所示: class=“org.springframework.jndi.JndiObjectFactoryBean”>
& q9 \% e5 o4 b( N, _* D/ P U- k" U {1 g
java:comp/env/jdbc/myds
% Z0 b# {" z; K8 A ! t& Q# y4 j; N3 z8 s
2、有效的 Session 管理: Dao类继承HibernateDaoSurport后,Spring 提供了 HibernateTemplate,用于持久层访问,该模板类无须显示打开 Session及关闭 Session。它只要获得 SessionFactory 的引用,将可以智能打开 Session,并在持久化访问结束后关闭 Session ,程序开发只需完成持久层逻辑,通用的操作则由HibernateTemplate 完成。 3、统一的事务管理。无论是编程式事务,还是声明式事务, Spring 都提供一致的编程模型,无须烦琐的开始事务、显式提交及回滚。 建议使用声明式事务管理,Spring 的声明式事务以 Spring 的 AOP 为基础。可将事务管理逻辑与代码分离。代码中无须实现任何事务逻辑,程序开发者可以更专注于业务逻辑的实现。声明式事务不与任何事务策略藕合,采用声明式事务可以方便地在全局事务和局部事务之间切换。 Spring声明性事务有两种配置方法,一种是xml配置:
) f6 F: m3 n2 a: w& A( H* X$ h 5 o8 S' \/ {7 I1 ]5 [- f
, q3 l! t* v, x& H W2 H
! d4 @4 \2 e& f$ m7 E, _ 6 F/ l5 c0 o' x+ {
8 z: l; |' R1 f% Y8 t
% B1 z9 ^$ P$ |" J, i
$ q$ |# o$ X1 c$ }
) l5 Z6 B+ ?' f* c8 { / h& o) ^6 m, A) a
9 t7 B4 e5 d% g0 N3 }& \
, G, g0 L3 L$ b5 s7 M 1 I- D9 }& S. \* H" r: `- {) N1 L
7 h0 F$ O# v. c6 Q% p3 M: o
另一种是通过注解,在需要添加事务的类上注明 @Transactional & P+ f" b3 Y3 I
Spring2.0之前事务的写法* c$ p3 G( M" `" n9 r- ~9 ?
, g9 F% Y7 B8 j* T1 w2 R7 O) R8 W( I& e4 A5 P
class=”org.springframework.transaction.interceptor.TransactionProxyFactoryBean”
9 H9 \6 c a U: `9 G) k2 t8 m' g5 m5 D# L3 r1 o7 f" V4 q
abstract=”true”>% \$ D& Z/ A, B* Y' M
v% A' V/ Q: z2 v# H
6 ?+ A; Z# j: ?: H
7 M. u& n5 t( U$ N0 V8 X
+ i" b) f1 C- q3 w& M! V f, y# T PROPAGATION_REQUIRED,readOnly
2 L+ _& ]- b: k6 V0 r
7 M% Q4 ~9 @7 J% @" I& I3 f PROPAGATION_REQUIRED
# V* k" O7 v7 K' v+ ^ r; b2 C# d0 d/ _- [
* S: Q v9 g X
$ o5 t* d! o( h$ m2 h4 \: i1 R* P0 y- |& Y4 d' R
| ) y! p$ w1 F8 Z: T
% L3 Z; u* V: ~' D T# j- 谈谈Spring对事务的支持
/ A1 ~, |& s; T p9 ^% N
5 H# R0 j0 j9 ]5 H2 F
i3 `& O4 r2 `. P0 i! `5 n# G1、声明式事务管理:
1.流程:由客户端访问—-aop监控—-调用advice来追加事务 2.做法: 2.1 在配置文件的头中引入xmlns:tx 和schema的文件 2.2 2.3 注入数据源 6 O% N( {: X5 W7 x. x/ ]1 |* A( p3 s
4 t/ Y9 h% E% E
+ k+ b9 j# `! T- J8 b: C* x9 I9 K9 {6 J5 U; h6 P9 A9 M
V% \3 X/ e E2 l& R) U) _9 U0 G
; ^+ v$ u% _1 C l: r# S2.4 由spring实现的事务管理,但需要注入数据源 4 G: X4 n; @! o: l+ I
# x( Z% y% q. J( r* z& D: ]
9 K, _9 D8 O5 m( l* o2.5 事务监控所有的方法(事务加强) 7 k2 t) |, |+ E8 h
0 U# }: G1 T- T* p
, y+ v7 I, ]3 E9 D
' ^6 z' a9 g+ y* O- M7 T5 q& z' g" w/ J4 i1 X
2.6 定义切入点 8 t! w& F& S# P4 e$ U9 |$ L% S
) q! w$ z; z- N1 S4 n/ f- t- A, s% B# S2 P" [2 {$ k
7 u7 q' t3 `. x0 D4 {$ ]+ e
" s- i4 l. @3 ]2 {+ \* z2、使用注解实现事务管理: 1.注解@Transcational (可以在类上,也可以在方法上) 2.在配置文件中同样需要注入dataSource和spring的事务管理 3.使用注解的方法来追加事务 注解驱动
' Z0 @! f1 `0 D3 T+ N! C3 n( `* w3 j3 P( ?- K
如何在Spring中使用Hibernate的事务:, V+ }* Y3 X" L! y& m$ S
, e' _" @5 x' y+ r- N7 y1 M
, s( b* Z6 n. T# S, \. Y
8 L$ o" W2 p; S, s1 C' x如何在Spring中使用JTA的事务:
& }1 U. i$ G* R" M8 V1 I7 f( X
, A- _* P! b9 u8 _8 Q |