Spring' y1 N3 N! h/ d; g
- 是什么?5 N. }6 T) G8 K h: t
. N. p% o9 H1 K, i
Spring是基于JEE的轻量级的应用框架
; n/ L- G8 H" Q6 t- 有什么?
3 l# O6 K# }. R( `2 t* x8 Y: p6 V
' o l! r2 D/ k
4 ]1 k! p* P7 a, a3 f% K
每个包的功能: Spring MVC:spring 本身提供的web 框架 WEB:集成其他的web 应用的框架,或者说是对其他web应用框架的支持。如struts,webwork JEE :集成一系列的jee的技术(对JEE技术的支持) DAO:封装了JDBC;(对JDBC的支持) ORM:提供了对ORM工具的集成(支持) AOP :面向切面编成 CORE:spring的核心包,提供bean的工厂和IOC容器
/ h' R9 o8 n9 Y7 V8 M- 能干什么?1 M7 d( ]9 W0 o2 W" y* v6 F) n' N# d
2 I0 l/ }' a) {0 y' S* C3 _
把一系列的jee的技术有效的组合在一起形成以良好的系统
' j o' [1 ]+ ~- 怎么用?( C& C' i5 f8 i" x
6 G( B4 s: V+ }/ ~$ }
- 搭建web工程,引入spring的jar包3 v0 m* {# w; c @+ ~1 y
- 在web.xml中添加如下配置- K$ z( f: |% C5 S: c
Y* Z7 V2 a& K0 g8 p
9 e& O/ {7 d" V! |! S( {
9 G5 @; o) Q1 O" F5 B8 V: B: }
contextConfigLocation
1 `, P: ^6 d9 e! C0 n; E6 V; F classpath*:applicationContext*.xml
1 L) S7 E$ _! k/ U " Z- P6 q; d/ G
" m: J, S$ U+ J8 B2 }7 r
struts21 z7 j! ?; d$ s7 B5 X
9 R3 |+ h2 p' O5 l# d
org.apache.struts2.dispatcher.FilterDispatcher( w7 O0 n" M) i4 p* M- X
2 W7 C5 g- b' r( U- x
; i0 h3 T: ^- u9 s; [( e 0 t- ] K# Y; Z, w, V5 E0 O
struts2
4 {3 [+ q4 }% j( p/ f2 I /*) P. H8 u! [; C* e, m
( E; X+ ^5 x. g7 C9 F
9 `! Z- @" \, K$ L N# `: Q& d; e
" y1 V( e+ j2 m& O4 `* d+ }
org.springframework.web.context.ContextLoaderListener
' T9 ~3 N" v! \& } * n) I- E6 M* a+ n
- 部署
$ ^5 @( V+ J" M7 ~$ T7 E; d" _9 C1 T" a$ k- s' r
6 e* w8 m' G0 p: l/ j w* Y
( D* y6 x0 n% n- |; U+ Q
% M! j& b, H5 r- C. c: B5 RBean :是指受spring的ioc管理的对象称为bean 容器 :(与jee的容器类比) Jee :提供组件的运行环境和管理组件的生命周期(不能单独存在) Spring :提供bean的运行环境和管理bean的生命周期(可以单独存在) , o1 _! @* y; O1 w6 X
9 b; c3 Q5 S8 [$ ]8 O" e9 x; {
- DI依赖注入
3 v5 l8 }/ _- M, X
1. 应用程序依赖spring注入所需要的对象 IOC和DI是对同一种事情的不同描述 2.setter注入: 在配置文件中将接口的实现配置为bean在应用程序中注入bean 例如: 在配置文件中
. _. t7 M+ E: ?4 [8 x% k* \9 g8 u1 o0 R" r
. ], D' U& l2 p6 U) b& z1 \" O9 ^, T$ f
在应用程序中 Public DBDAO dao ; Public void setDao(DBDAO dao){ This.dao = dao; } 3.构造器注入 3 p2 S6 S: q- O2 A/ s/ s
4.ref 表示参照其它的bean 在参照的过程中一定要注意死循环 5.自动装配———–〉no 自动装配根据名字来匹配相应的bean 尽量不要去自动装配 6.lookup注入 7.singleton 1.单例模式是整个的jvm中只有一个实例 2.spring的singleton是指在spring的容器中只有一个实例 一个生命周期中只有一个实例 8.DI的优点: 1.程序被动等待,强化面向接口编成 2.切断了对象或组件之间的联系,使程序的结构更加松散,运行和维护更加简单
3 ]+ e$ \( w& b, L- Aop面向切面编程 Y/ a5 F6 k7 s) p2 N+ c( p9 p- K9 [, a
8 y) p' h) H7 {
1.AOP面向切面编程 一些较好的模式或者是示例—-范式
" g' x! i n/ U: B 切面:一个切面代表我们所关注的一系列的共同的功能点(模块之间的共同的功能点) 2.AOP的思想: 主动—->被动(追加功能)
/ b7 }' `5 \4 a k* L 3.AOP 的概念, b: `0 o$ T" ^( {; a
1.切面 :我们所关注的功能点 2.连接点 :事件的触发点(方法的执行) 3.通知 :连接点触发时执行的动作(方法) 4.切入点 :一系列的连接点的集合 (连接点的模块化) 5.引入 :扩展的功能 6.目标对象 :包含连接点的对象 7.aop代理 :实现机制 8.织入 :把advice和目标对象连接起来 4.AOP的事件机制% _' D* n1 r& V& b6 g( M) i# D" a
1.通过切面找出一系列共同的功能点 2.找到目标对象(在标准的spring 中 接口的实现类为target) 3.找到切入点 4.确定连接点 5.通知spring AOP,查询xml文件,通过代理找到advice。 6.由aop代理来实现动态织入 y/ E- G) M c# U& {( L
, e1 \" Q! [4 w0 k
; e* i" ]9 E$ y& r1 s/ i, q9 g A6 k( H% }( n* c/ T
: E/ i7 [2 H% }! l, A( Y8 a$ P; Z1 Z
% r) m3 c: r9 g0 f5 _9 k
0 u R5 d; _6 u' `8 [ Y( w! ~5. AspectJ( [! p( o/ J* n; Q. q
5.1.在xml中配置比较烦琐: ^1 y# j& c' W) i( J
所有的入口必须从一个代理(ProxyFactoryBean)开始
! o$ I& y( `! y( F/ I/ B ' C4 l" N6 A/ n( b. Z
5 T) N: C. i7 g! M: [ t* H5 I3 K2 t 6 e9 J" p5 a+ q; J0 H
. ]& v% q* X) e9 k8 h- e( l( R X9 e! y
8 d! d' r' [$ ] ( ^. k/ m9 V# u' F$ l, d" a5 L
- H$ k6 ]; W: o* U8 K
expression=“execution(* com.javakc.aop.MyTarget.t*())”/>' Y; M1 C9 ^( s. x: c3 g
+ V5 a* a1 X) }8 f4 l 2 p3 d3 }, s3 i( w
. D0 x9 `8 N8 |: g
6 R' E4 Q0 [- ?, l" Y3 d$ [$ q1 S
3 L z- |9 n. k1 s5.3.使用注解的方法相对简单
3 `4 r* Y( I" g5 A: l @AspectJ的基本语法
: c# `3 L0 T+ t3 i 1.@Aspect声明一个切面,将一系列的共同的功能定义成一个切面$ B* d" b3 l' ?/ i
直接在类上定义@Aspect
$ ]/ B) `/ }& _3 W; W0 } 2.@Pointcut声明切入点
: }9 f' h, u% W1 g& p$ }+ s 2.1、用一个专门的类来定义pointcut,类中的方法名就是该pointcut的名字 p+ z1 a7 C) b- M
2.2、可以使用匿名的pointcut* G5 n+ x3 [1 Z W; Z4 ~
2.3、执行切点的几种方法$ j% ?1 C! }- r) M: C8 S7 O
2.3.1 execute(public * 包结构.*.*.(..)) 可以指定到具体的方法
! c8 f3 K5 R: ?) w/ D5 | 2.3.2 within 指定到包,不能指定到类
3 d. F3 L5 a3 y0 X within(”com.javakc.spring..*”)! h! |* E' I+ O
2.3.3 this 指定到实现接口的所有的实现类' V; [$ \" [7 S! ~: e8 A
2.3.4 target 指定具体的实现类
9 _) N% E, D+ n( j8 S) A# r 5.4.advice的五种类型的示例
' e! ]4 H( w( O( @- ?( G 客户端必须从接口走才能得到监控,实现想要追加的功能
. `- z$ O1 v) q6 d4 L: k( \ 5.4.1.@AfterReturning(pointcut=”” returning=”retVal”); @/ n6 @4 I* U z9 B$ M
追加的方法的参数名字一定要与retrning的名字相同
- \6 h) o: _8 {, s! ]$ S5 M( g7 ~2 b 在注解@AfterReturning中必须加上pointcut和returning两个参数' F7 Y# G: A$ Q, e' w6 B# O5 S
pointcut指所要监控的目标对象的方法! M, s$ U' P. b' J/ f* l J0 `
得到目标对象的方法的返回值,来作为参数,进行下一步的处理,参数没有顺序,按参数的名字进行匹配# e( d) Q3 B8 F
完成追加的功能
$ p& Q7 Q* S! }+ o' S3 D- ~ 1 定义一个pointcut,通过方法名来作为pointcut的名称来引用
, Z( _) \( h& [2 R4 [; ^3 z (1).@AfterReturning(“com.javakc.spring.schemaaop.TestPointcut.t4()”)
# u& s2 w6 P A5 M4 I8 Z& m4 {# x i4 m (2).6 S/ K9 ~" S- x
2.直接引用匿名的pointcut! B- X* H! M7 k. ?! T( k
(1).@AfterReturning(“execution(# v; Y2 I- `" x- X. Q6 O) a8 k
* com.javakc.spring.schemaaop.Api.test4())”)% i) J' h r4 l, e% x! v
(2).@AfterReturning(pointcut=8 d) F4 F% Z# Q/ E. m; F
“com.javakc.spring.schemaaop.TestPointcut.t4() &&! Z4 w+ X2 S( H) K; g, O$ \: {
args(str)”, returning=”retVal”)
! [" W; |/ \! T) ~ @AfterReturning (pointcut=”com.javakc.spring.schemaaop.TestPointcut.t4() && args(str)”,returning=”retVal”)! Z6 H+ I; Z5 \# l8 j
public void testAfterReturning(String str,Object retVal){* t) W8 n6 i( ^+ w8 z
System.out.println(“afterReturning1=>”+retVal+”=>”+str);
: \0 c, \; v- u% u, P1 a }
% }# \6 Z4 N u( }/ ` 5.4.2.@Aronud
! R& [8 T) n- `2 g 注解@Around环绕追加功能;2 g. J6 |9 q) w. {, E% `+ d; ?8 e* {
在执行目标对象的方法的前、后追加功能;' A* g. V' [. O+ B4 P
必须有参数;第一个参数的类型必须为ProceedingJoinPoint;
! A" H$ q8 y0 |) z {" h 通过ProceedingJoinPoint的实例的proceed来调用所监控的
: z0 C5 x2 m& N) f1 C4 e 目标对象的方法
! V9 E3 S# m, b 1 定义一个pointcut,通过方法名来作为pointcut的名称来引用. _- F( b4 n4 }8 h$ {: R3 B8 [* I; m
(1).@Around(“com.javakc.spring.schemaaop.TestPointcut.t1()”); ^ k; r: Y& l% S- U- L
(2).@Around(“com.javakc.spring.schemaaop.TestPointcut.t2()% N, }( R9 l, d) |" g$ a2 p9 c
&& args(str)”)
! |0 Y) D0 _; @0 @& g7 _ R 2.直接引用匿名的pointcut/ p8 s* B9 Z' m1 f' ?( C2 }
(1).@Around(“execution(
/ R7 z f$ \' n) Z/ B * com.javakc.spring.schemaaop.Api.test1())”)
+ I$ P* T) L- O0 t6 I (2).@Around(“execution(
' P3 [1 Q; a7 B6 V' C4 P* ~ * com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)4 j" P1 r8 z- N2 M& b% d1 e+ \" [
// @Around(“com.javakc.spring.schemaaop.TestPointcut.t2() && args(str)”)% @' I/ {( e3 t- H( h0 n4 Q! D1 @
@Around(“execution(* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)
! U8 Y* o2 A+ p7 f# T1 h q2 M/ X! o public void testAround(ProceedingJoinPoint prj,String str) throws Throwable{
6 G* i ~ M7 k- o4 T( q/ t6 J x System.out.println(“around1==========before1pointcut==>”+str)9 O; f7 N7 B/ `) n$ e$ I# |5 j! u
Object obj = prj.proceed();
5 T' Y2 l+ M- v; \( W& q System.out.println(“around1==========after1pointcut==>”+str);
5 N ]/ `% S6 ]( h }9 C1 l Z% V/ q) y4 _
5.4.3.@Before, Z G; d- D9 r5 b! w2 `5 }, l/ k# }
注解@Before在执行目标对象的方法前追加相应的功能
5 ?6 f% J% a5 e+ x) C0 f 1 定义一个pointcut,通过方法名来作为pointcut的名称来引用7 w! } Z H$ y e4 t; t
(1).@Before(“com.javakc.spring.schemaaop.TestPointcut.t1()”)4 u& c+ y' H; ?) y* f/ a- a
(2).@Before(“com.javakc.spring.schemaaop.TestPointcut.t2() && args(str)”)$ X' D, \ d S8 ^6 R; H) f1 W
注意args后的名称与参数名相同: T- d; i+ e! I! P0 O# B" d0 a. _+ d
2.直接引用匿名的pointcut
3 ]* A6 g* m- q5 J/ J (1).@Before(“execution(* com.javakc.spring.schemaaop.Api.test1())”)& N% e! Y, n- P( U& G
(2).@Before(“execution(* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)
$ F( c# E# y! Q! X5 [7 n 注意args后的名称与参数名相同
# T1 S/ K- G `% a! O2 h2 k6 e) J6 C( E // @Before(“com.javakc.spring.schemaaop.TestPointcut.t2() && args(str)”)# {& K* V7 }5 J
@Before(“execution(* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)
0 k, B6 `& S, S* Y& V public void testBeforeParam(String str){
6 C ]0 J/ \: j9 ^ System.out.println(“before1=param=>”+str);1 D3 o4 T# W& A) |$ c
}
8 {/ ]+ J9 Q0 O 6 f. K2 G% ]/ f# g% l
5.4.4.@After
. B0 i+ X z- C; {5 I2 F6 G. _ 注解@After在执行目标对象的方法后追加相应的功能
& _: B0 s$ D3 U 1 定义一个pointcut,通过方法名来作为pointcut的名称来引用
; _3 L( @ C3 V+ N7 j (1).@After(“com.javakc.spring.schemaaop.TestPointcut.t1()”)
& v9 i0 x8 @7 }( r6 Q 2.直接引用匿名的pointcut+ S" [! w& u. Z; z+ w+ Z
(1).@After(“execution(* com.javakc.spring.schemaaop.Api.test1())”)$ X. X- {$ r& d4 b
@After(“com.javakc.spring.schemaaop.TestPointcut.t1()”)
- n0 Q# S& N0 `% t public void testAfter(){: b& q( l" W7 a z7 K ]: A
System.out.println(“after1== >pointcut”);
* e# q+ H/ n; \7 b9 N }
: V" L% Y. d" V, Z) G 5.4.5.@AfterThorwing" d; Y y5 G9 V3 Z
- l+ @* y, s3 U# I0 [
! M' s5 U3 {: ?2 I6 o9 T, b- 描述一下spring中BeanFactory和ApplicationContext的差别+ n# g" N: y: X8 t- I8 n, t( N
9 o/ r+ H% ]% g# f, |3 @" O8 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”); S3 P, G1 }" `; k
- 谈谈spring对DAO的支持
) {+ X) O0 p0 S7 B. V5 b
# [* y& |6 F8 ^2 f$ a% e d+ L. E
Spring提供的DAO(数据访问对象)支持主要的目的是便于以标准的方式使用不同的数据访问技术。' E+ q, p/ C. E6 P0 L
简化 DAO 组件的开发。" u/ X* I; {( M5 m2 {
Spring提供了一套抽象DAO类供你扩展。这些抽象类提供了一些方法,用来简化代码开发。
0 Q. y9 m! P& h, [ IoC 容器的使用,提供了 DAO 组件与业务逻辑组件之间的解耦。所有的 DAO 组件,都由容器负责注入到业务逻辑组件中,其业务组件无须关心 DAO 组件的实现。; v" M4 G6 V6 P! ^. ]# g
面向接口编程及 DAO 模式的使用,提高了系统组件之间的解耦,降低了系统重构的成本。
# {1 O- {% o& A3 s 方便的事务管理: Spring的声明式事务管理力度是方法级。$ g; [7 w$ Q( g: v+ D1 `
异常包装:Spring能够包装Hibernate异常,把它们从CheckedException变为RuntimeException; 开发者可选择在恰当的层处理数据中不可恢复的异常,从而避免烦琐的 catch/throw 及异常声明。
1 U6 |0 X+ r4 {/ s
' ^+ S+ G# R4 I, X% S0 e3 f
3 K6 m* O* @: {6 J, W- 谈谈spring对hibernate的支持
" r( `' x- E5 M- c$ C$ I7 G9 S9 H, Z1 n8 R
在所有的 ORM 框架中, Sping 对 Hibernate 的支持最好。如 SessionFactory 的注入、HibernateTemplate 的简化操作及 DAO 支持等。另外, Spring 还提供了统一的异常体系及声明式事务管理等。
! d; ~, x( {% g) m7 k; ` A7 @% _+ ` 一旦 Hibernate 处于 Spring 的管理下, Hibernate 所需要的基础资源,都由 Spring 提供注入。Hibernate 创建 SessionFactory 必需的 DataSource ,执行持久化必需的 Session 及持久层访问必需的事务控制等,这些原本必须通过代码控制的逻辑,都将由Spring 接管ataSource, SessionFactory, TransactionManager等,都将作为 Spring 容器中的 bean。将这些bean 放在配置文件中管理。
1 B( J1 O) f2 g 1、通用的资源管理: Spring 的 ApplicationContext 能管理 SessionFactory,使得配置值很容易被管理和修改,无须使用Hibernate 的配置文件。详细配置如下:8 ~4 M+ P, n# q0 [8 O9 e0 f
+ {4 `0 X3 V! g* ~
class=“org.apache.commons.dbcp.BasicDataSource”>& R% e0 J$ c- S3 b+ T
* o L& u7 Y, s
oracle.jdbc.driver.OracleDriver
' S0 A# E1 z6 p: V0 p/ W ' D E4 p3 \# Y( m# i! G
9 p+ y# e. S; X5 k/ i
jdbcracle:thinlocalhost:1521rcl
0 m* L# O- V2 }
. W1 G' P8 Y$ Q0 T+ F8 X 4 f: q* Y& z; J7 k. E: C0 w e
javakc2
7 {/ w" Y( y- B. b
i0 y) r% c* g, k4 L# m) S! M
2 D$ G1 t5 J) k* {4 V- x" V javakc22 r7 }! H2 m) |0 y6 U0 H- }/ X$ @
0 e1 p1 p% e, i. k8 a; n # [& p4 L" j7 t; z
' e8 J1 R' w* E S# w, ?/ A class=“org.springframework.orm.hibernate3.LocalSessionFactoryBean”>* \0 }- y% W2 n( T5 I
4 U9 q9 [* }' Z4 G
; P$ N" V) A4 F) P # S/ M9 ]9 C# [$ M5 d. ~: e2 q* P
com/javakc/spring/h3/UserModel.hbm.xml; h+ ]3 O3 G8 ~0 i
9 l: O: B2 p! l5 D& ]7 N" O9 G
; i2 O* m6 L3 f# x
% w, N- L) V7 } `3 I
0 p8 i# g; o& D) S3 U* k hibernate.dialect=org.hibernate.dialect.OracleDialect
( U5 T) I1 o3 ]5 j4 t
( R5 ~: C1 K/ U' \: J8 { % K, C# Q2 |, Y. y# z9 q
8 m9 ] A% j: A7 I/ a3 Y1 W
4 T' l* f) c3 B) X
- a. G: w' k" L
9 n( P' A: S- N: x+ j8 q5 @ 如果需要使用容器管理的数据源,则无须提供数据驱动等信息,只需要提供数据源的JNDI 即可。对上文的SessionFactory只需将dataSource的配置替换成 JNDI 数据源,并将原有的 myDataSource Bean 替换成如下所示: class=“org.springframework.jndi.JndiObjectFactoryBean”>& [: m* q8 H. b9 S
% @. P4 u8 ^* R
java:comp/env/jdbc/myds+ n9 }" Z, g9 U. {( Y
! B6 M* I* Z5 Z4 h
2、有效的 Session 管理: Dao类继承HibernateDaoSurport后,Spring 提供了 HibernateTemplate,用于持久层访问,该模板类无须显示打开 Session及关闭 Session。它只要获得 SessionFactory 的引用,将可以智能打开 Session,并在持久化访问结束后关闭 Session ,程序开发只需完成持久层逻辑,通用的操作则由HibernateTemplate 完成。 3、统一的事务管理。无论是编程式事务,还是声明式事务, Spring 都提供一致的编程模型,无须烦琐的开始事务、显式提交及回滚。 建议使用声明式事务管理,Spring 的声明式事务以 Spring 的 AOP 为基础。可将事务管理逻辑与代码分离。代码中无须实现任何事务逻辑,程序开发者可以更专注于业务逻辑的实现。声明式事务不与任何事务策略藕合,采用声明式事务可以方便地在全局事务和局部事务之间切换。 Spring声明性事务有两种配置方法,一种是xml配置: , M4 \/ m; Y; Z) w5 U, G
8 Y+ \2 {7 d% r; D- q) b
6 U3 q4 _4 e2 R
1 q, Z9 u7 x+ E) K( @ 2 v: b$ b" e3 Y8 A
K& n% g3 }: g( D8 s( [" T* B
, ]! s8 u. f! A9 @0 U9 k! K! `& R
: J! u) `" \& [$ y
, K7 ^! R. i1 s% }; L
: n# S1 S& w# @/ m. c/ {) o( R
. g/ F, W" b; Y1 g W* `
1 z c0 w1 L( ^4 J" k9 |1 C ! n, N/ d$ P. y( O
6 C3 y" _ w' v, a8 l
另一种是通过注解,在需要添加事务的类上注明 @Transactional + k% o* O3 s2 c$ K4 C- s& v- C
Spring2.0之前事务的写法
7 [; s$ T4 s! ?9 I* d
7 m0 P0 ]4 c8 e A! r
* |. \ U: C! |3 ^1 M class=”org.springframework.transaction.interceptor.TransactionProxyFactoryBean” q! E1 Y6 X% @$ [ H8 j
4 u0 k5 J* I$ t7 o' Q1 ^2 @
abstract=”true”>
. Z) Z/ W/ Z- k P k/ ~" l. j# I4 W+ M) ]% S
2 D" a2 | w! D8 N9 E @, U& D9 ^* d/ j' p
. B' V1 Q5 N9 `! d4 w PROPAGATION_REQUIRED,readOnly# r K1 H$ h6 l" p2 m2 E
- Z8 L0 E b: \7 ~
PROPAGATION_REQUIRED2 S! A$ P2 \; t. Y% p
# V+ y+ y3 I8 b. `( T% v) x; I
1 s5 |9 D: P& v! r
0 F. z' r+ H" p- x1 `
8 _' B% c* J; v- |2 ]9 B- x% y | + u6 F) Q& m3 Y
7 O! x0 T- g# T8 \+ m: o
- 谈谈Spring对事务的支持8 O7 {1 J5 N' g
U1 N, @6 {6 |0 N- ` P5 D" ]
2 e% x. K! T1 e/ A' X6 T) X
1、声明式事务管理: 1.流程:由客户端访问—-aop监控—-调用advice来追加事务 2.做法: 2.1 在配置文件的头中引入xmlns:tx 和schema的文件 2.2 2.3 注入数据源 / x6 H+ ~6 Y& \; |9 I, `) V
* Y3 V# [& q! e
( F! K7 t r' I* y. P& G6 P( n- e9 C: ~- ]% f
& s% `* _. K; W& j0 z( |4 ~& V$ L5 c/ R
2.4 由spring实现的事务管理,但需要注入数据源
. Y9 ]2 t# Y. L. m+ u9 }6 k ]. S, h" @( V& r
2 ~! W" M* @2 T. Z+ x6 ]9 \4 h2.5 事务监控所有的方法(事务加强) $ t' S' C$ `) o" G
- }; }" z1 [* z) j
& m* S8 q. _# f0 U" f
+ _, q3 t- V$ o3 a& `; \
+ f9 O2 z; ?+ l8 M; C2.6 定义切入点 9 V( {' `' o% _; S6 r0 j
" @5 L! \ @! r$ L
9 V% E7 u! m# n( y2 y9 f* H/ a' c
, Z* L9 C% |" B+ ~& j! R$ t
, n' e, F2 O0 w, [6 i' ~- D2、使用注解实现事务管理: 1.注解@Transcational (可以在类上,也可以在方法上) 2.在配置文件中同样需要注入dataSource和spring的事务管理 3.使用注解的方法来追加事务 注解驱动
1 n9 o! f" E1 b( a
) e0 k5 v5 F1 y4 n1 B% p/ T% U如何在Spring中使用Hibernate的事务:: A/ b8 e2 x! o* ^
9 k5 Q# `# p- R# N* t, U3 r i5 o
5 I9 `) _& x' ^2 A6 y' a
. c/ L) F/ ?' @# A, w, E- [& X
如何在Spring中使用JTA的事务:" }, |1 u# x. Z
7 h: ]+ _$ z1 L
|