Spring$ w( R5 A4 K% x, c/ ~* w
- 是什么?0 K$ C5 V5 P$ n
# Y4 p2 R6 x0 @
Spring是基于JEE的轻量级的应用框架 4 [1 S/ S1 Y- \6 T
- 有什么?
0 L$ a4 j# U, W& E, |- `8 L4 E/ b
: B2 X$ a0 R- G5 Q: l3 W4 n1 _7 m & w5 Z% ?8 i6 i( s t( M
每个包的功能: Spring MVC:spring 本身提供的web 框架 WEB:集成其他的web 应用的框架,或者说是对其他web应用框架的支持。如struts,webwork JEE :集成一系列的jee的技术(对JEE技术的支持) DAO:封装了JDBC;(对JDBC的支持) ORM:提供了对ORM工具的集成(支持) AOP :面向切面编成 CORE:spring的核心包,提供bean的工厂和IOC容器 - d" ]& u7 @* G+ q( \+ C9 v
- 能干什么?$ Z: G9 f3 C/ k8 t* d0 E
3 U( b" B; W' {0 r6 t' \1 f. \
把一系列的jee的技术有效的组合在一起形成以良好的系统
8 X& e! f: @+ \' Q0 h0 K7 P- 怎么用?
7 d3 x+ R3 z4 V
- L' M- c7 w2 p& a" y1 p- 搭建web工程,引入spring的jar包+ m9 m* r9 H& M
- 在web.xml中添加如下配置1 A7 m+ s8 K+ E; B% D( \7 X
+ w- Q1 {# O+ z. ^3 r
% N0 C/ X6 W% ?) l2 H7 \2 x6 h$ l
contextConfigLocation
! ?3 M% F& K' d1 B1 @ classpath*:applicationContext*.xml4 K' a# f; ^$ v. C. v( J t
- a4 `/ Z2 N" ?( E 9 J m, ]% ?' l' L) v% R, X: d
struts2
; r3 ~, W" S8 E 1 T! h: T( ? V h( X; `
org.apache.struts2.dispatcher.FilterDispatcher
d/ P/ R; q* u+ ]/ d3 p ' u# N6 y" e; \. ]: i! F: z+ X: k
! h7 z) F+ o) M5 K! ]
! |- S0 X* U1 E. L4 D4 B$ Y# _
struts2" Z( v/ m1 I) r* \' O
/*$ J1 r0 t) e L( H5 d4 l# M; h
* l7 `$ `. t: e- ?
. @% s5 d( P3 r P
1 h+ `! F0 _% e org.springframework.web.context.ContextLoaderListener
) c9 z; g% c. M$ _/ b+ r$ X q% T 7 ?' B$ T& D! z! q6 a
- 部署; r; x; R+ \' v. o& p" p# p+ n2 V
' j' X% w% k- q* w
& V& u5 J% u% `8 Y- n; y3 N5 \ A
6 E4 N% |) R( K* b/ e& S& N1 r7 Y/ G4 J3 V& R
- 容器和bean
" t0 E8 E# \0 D3 @
Bean :是指受spring的ioc管理的对象称为bean 容器 :(与jee的容器类比) Jee :提供组件的运行环境和管理组件的生命周期(不能单独存在) Spring :提供bean的运行环境和管理bean的生命周期(可以单独存在)
* f8 d3 D; R" y# M, ?0 G
& l# G" i$ ?3 v6 t: b4 A) b- DI依赖注入- t# a0 q+ t% m" _. Q
1. 应用程序依赖spring注入所需要的对象 IOC和DI是对同一种事情的不同描述 2.setter注入: 在配置文件中将接口的实现配置为bean在应用程序中注入bean 例如: 在配置文件中
, z8 B! W& o2 U$ e/ L2 N* V9 V# M) F! j; q5 f
: W; a. ~6 Q6 Z# i' C) X在应用程序中 Public DBDAO dao ; Public void setDao(DBDAO dao){ This.dao = dao; } 3.构造器注入
9 l7 U+ G) Q" n, v4.ref 表示参照其它的bean 在参照的过程中一定要注意死循环 5.自动装配———–〉no 自动装配根据名字来匹配相应的bean 尽量不要去自动装配 6.lookup注入 7.singleton 1.单例模式是整个的jvm中只有一个实例 2.spring的singleton是指在spring的容器中只有一个实例 一个生命周期中只有一个实例 8.DI的优点: 1.程序被动等待,强化面向接口编成 2.切断了对象或组件之间的联系,使程序的结构更加松散,运行和维护更加简单 8 C. d0 G6 F" w3 }' n
- Aop面向切面编程# j6 y7 S: S7 G [5 i# n5 w
1 ], d$ v3 m! I( `; Z: |! V% o
1.AOP面向切面编程 一些较好的模式或者是示例—-范式# a* M7 [. a# x0 c* P+ V6 v1 Z0 `! I1 _
切面:一个切面代表我们所关注的一系列的共同的功能点(模块之间的共同的功能点) 2.AOP的思想: 主动—->被动(追加功能)
& l2 M9 V& d. x* K. h( x3 Q4 B 3.AOP 的概念
4 F9 J# B9 |% E5 K* L 1.切面 :我们所关注的功能点 2.连接点 :事件的触发点(方法的执行) 3.通知 :连接点触发时执行的动作(方法) 4.切入点 :一系列的连接点的集合 (连接点的模块化) 5.引入 :扩展的功能 6.目标对象 :包含连接点的对象 7.aop代理 :实现机制 8.织入 :把advice和目标对象连接起来 4.AOP的事件机制4 ? {+ F+ B% f0 [: F, h& ~
1.通过切面找出一系列共同的功能点 2.找到目标对象(在标准的spring 中 接口的实现类为target) 3.找到切入点 4.确定连接点 5.通知spring AOP,查询xml文件,通过代理找到advice。 6.由aop代理来实现动态织入
" d3 O" e) L3 W5 U8 q- f3 w
. l0 b5 H4 x! S- g. B) W$ u3 F8 g8 a [- g; _$ f6 H
y- T! G5 y) W0 b9 C* h* `2 N5 [ q7 l+ Z; K4 N+ z6 ?; U
, a- [8 e+ u! I. O3 x* }
; Q# w- b& ?: _5. AspectJ% ~! d* u# L/ z9 \3 \
5.1.在xml中配置比较烦琐
( K) f! N4 _0 z6 K i/ B9 ^9 ` 所有的入口必须从一个代理(ProxyFactoryBean)开始* H: J. _# \2 M5 C4 d- V; P' m3 R
3 r! A5 h( O( u! c$ E$ t% k* v: r z
/ D1 z4 w) t: d 4 Y- ~$ x# i1 x" l, H. [
2 P- Y; a% D5 W# H- T; X
: A9 K' B9 D- A
; v6 B% q5 u7 y6 V, p6 [6 b) S
0 j( O! I% Q/ h1 } 0 g$ }$ D( d: ^) i) I' d
expression=“execution(* com.javakc.aop.MyTarget.t*())”/>
$ A9 [7 L8 S) q0 ` ( o2 O' }- l+ }, J
7 K/ J6 e3 k5 z
" C% s( L% c3 A' w2 U/ ~; D' n
# x2 ?6 E. x- |5 j3 s
* ?% W3 s8 Z! k
5.3.使用注解的方法相对简单
% ]' M; d! V4 Q8 r6 j+ k @AspectJ的基本语法7 J" l" y' B+ O$ P7 ^
1.@Aspect声明一个切面,将一系列的共同的功能定义成一个切面
/ I5 ]) x6 l' w2 d 直接在类上定义@Aspect' d$ h# V; L5 m
2.@Pointcut声明切入点, _/ g' v w8 m: T
2.1、用一个专门的类来定义pointcut,类中的方法名就是该pointcut的名字
0 _9 h- C. [, E- p' d5 \4 z4 Q 2.2、可以使用匿名的pointcut( t& U) \' ?6 Y
2.3、执行切点的几种方法
) f& T# `0 [, K& M4 M: } 2.3.1 execute(public * 包结构.*.*.(..)) 可以指定到具体的方法# A/ k) Y5 N& b; r" @: ?
2.3.2 within 指定到包,不能指定到类, q1 K4 o0 K& ], v7 B
within(”com.javakc.spring..*”)
9 N; ~ G, E% k9 b$ F 2.3.3 this 指定到实现接口的所有的实现类
% D, ?; b$ u. v* O ?4 u 2.3.4 target 指定具体的实现类
/ N) u( e$ Y4 k9 ~5 e+ L 5.4.advice的五种类型的示例
0 f% E0 V+ X* }7 M$ [; ~ 客户端必须从接口走才能得到监控,实现想要追加的功能# {8 \3 @4 x% G) B9 Z
5.4.1.@AfterReturning(pointcut=”” returning=”retVal”)
4 D [3 ? [; z2 Q0 ~3 \ 追加的方法的参数名字一定要与retrning的名字相同" U. w6 g( U% A5 D
在注解@AfterReturning中必须加上pointcut和returning两个参数
z3 ?- E8 ~0 [, k' R4 S pointcut指所要监控的目标对象的方法
, x$ S+ S7 l- t m 得到目标对象的方法的返回值,来作为参数,进行下一步的处理,参数没有顺序,按参数的名字进行匹配6 s' ~4 S' d* X* [. U: v9 F9 e! {
完成追加的功能
* }% D" s }, }( p3 b 1 定义一个pointcut,通过方法名来作为pointcut的名称来引用
( a- k! t. p; i) r7 f. ^0 g4 h3 ~ (1).@AfterReturning(“com.javakc.spring.schemaaop.TestPointcut.t4()”). u* M& D" P; N9 z& L
(2).4 [. @; M9 O7 k# [
2.直接引用匿名的pointcut
6 }- `- U* R" G4 n0 \( G0 Z7 M (1).@AfterReturning(“execution(% `8 h0 i) V3 v6 }
* com.javakc.spring.schemaaop.Api.test4())”)# Y$ G% X# i! _. o' n
(2).@AfterReturning(pointcut=
1 ?% n' w6 k2 s “com.javakc.spring.schemaaop.TestPointcut.t4() &&( I! T! j& }, l/ Q
args(str)”, returning=”retVal”)/ a& H4 K; l; E& ?3 _
@AfterReturning (pointcut=”com.javakc.spring.schemaaop.TestPointcut.t4() && args(str)”,returning=”retVal”)
' W9 |9 Y' ?4 h" `* o3 i, s public void testAfterReturning(String str,Object retVal){9 F: t+ _: S+ |& }
System.out.println(“afterReturning1=>”+retVal+”=>”+str);/ n1 ~, u7 m7 e" K2 S
}
% ~5 \# H* C% D, h- \( g* N* J 5.4.2.@Aronud
3 J; k& V5 [, T1 c 注解@Around环绕追加功能;" `& G6 w0 P4 j d
在执行目标对象的方法的前、后追加功能;7 B4 N: C9 d+ K# { E3 p: h0 m
必须有参数;第一个参数的类型必须为ProceedingJoinPoint;+ V1 }) z% f7 e, V% j
通过ProceedingJoinPoint的实例的proceed来调用所监控的
4 d$ O3 R+ ?( C; A3 r3 a 目标对象的方法7 I: Y, h: X, B! ]% y5 W/ u" N! Y$ D
1 定义一个pointcut,通过方法名来作为pointcut的名称来引用8 U& J! Z8 b5 L6 h4 N7 ?
(1).@Around(“com.javakc.spring.schemaaop.TestPointcut.t1()”)$ Y) h2 L- a7 T% Z
(2).@Around(“com.javakc.spring.schemaaop.TestPointcut.t2()9 X/ [. A) G3 A( M1 L
&& args(str)”)
. k3 d- u1 ~' |' J# n; b 2.直接引用匿名的pointcut& p$ M# G/ c; m5 @+ R ~
(1).@Around(“execution(
5 m& L. v+ \2 |9 b5 i; Z! m) f * com.javakc.spring.schemaaop.Api.test1())”)
G y' u! Y/ l' V (2).@Around(“execution(' ]* h+ p/ S4 A1 Z' B
* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)
) { Z+ H" h. L // @Around(“com.javakc.spring.schemaaop.TestPointcut.t2() && args(str)”)& I9 X: A, J+ m& r
@Around(“execution(* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)& y2 w; \4 b+ Q: E
public void testAround(ProceedingJoinPoint prj,String str) throws Throwable{
6 w. O; J( F3 B7 G+ h) p3 e- K System.out.println(“around1==========before1pointcut==>”+str)7 {8 d& B8 Q7 ?, O. ]
Object obj = prj.proceed();" t% N+ a# N( b9 ^* o: J
System.out.println(“around1==========after1pointcut==>”+str);
5 ]$ `5 l$ o2 Q6 G/ ? }
8 i& R# v4 L) X 5.4.3.@Before2 H" K9 z6 b& j$ t" Y
注解@Before在执行目标对象的方法前追加相应的功能; h7 s8 D; [0 X4 B
1 定义一个pointcut,通过方法名来作为pointcut的名称来引用8 x! o7 N/ [, m* p+ u, I
(1).@Before(“com.javakc.spring.schemaaop.TestPointcut.t1()”)* H8 W. y k- ^3 F+ w
(2).@Before(“com.javakc.spring.schemaaop.TestPointcut.t2() && args(str)”)
, G4 I3 B0 R1 l+ f& @ 注意args后的名称与参数名相同
' Q; z4 K7 s+ A8 S. ^* l 2.直接引用匿名的pointcut3 e/ h5 K0 e; x+ P
(1).@Before(“execution(* com.javakc.spring.schemaaop.Api.test1())”)
0 P% o, N# a; H8 n (2).@Before(“execution(* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)
8 D B' W* G" v* } 注意args后的名称与参数名相同6 Z( f7 ^3 n- O7 r: ^% s
// @Before(“com.javakc.spring.schemaaop.TestPointcut.t2() && args(str)”)
0 O f* O l1 M @Before(“execution(* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)
) d" {6 M4 p) |0 M3 a% ]. K public void testBeforeParam(String str){0 L! L7 B/ L" h+ F. s" R5 A/ m7 \/ ?
System.out.println(“before1=param=>”+str);
. |9 L# C0 W9 C }
: \! h# p/ K9 G9 U * d8 A0 G( t2 m4 K# R1 ^
5.4.4.@After
a2 P- i( F+ B 注解@After在执行目标对象的方法后追加相应的功能! g8 y2 ?$ [5 j
1 定义一个pointcut,通过方法名来作为pointcut的名称来引用
% d( n2 L% d2 G: R; n0 l (1).@After(“com.javakc.spring.schemaaop.TestPointcut.t1()”)
4 C2 Z G- W9 Q( A! T" {; s 2.直接引用匿名的pointcut
- o% r! l+ t/ P0 C8 G (1).@After(“execution(* com.javakc.spring.schemaaop.Api.test1())”)0 X8 T( j0 v% ]+ H+ [
@After(“com.javakc.spring.schemaaop.TestPointcut.t1()”)
/ p- N; M* e6 h% x F' A N7 R public void testAfter(){ P+ Y7 B8 m/ X, `
System.out.println(“after1== >pointcut”);
2 @3 Q9 h8 F: V9 C4 v }) y! D/ s( C9 l6 ^& s- T9 \
5.4.5.@AfterThorwing
+ b/ c! D7 \7 C0 P - C! G5 d, z3 v7 L" ?8 [3 Y$ A
5 S* B8 G5 g# l
- 描述一下spring中BeanFactory和ApplicationContext的差别8 l3 I+ \: a$ x3 ^- ]9 V N# l
% _5 H! G+ _0 w* n% }, O. u- W! N. L
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& b( L& W- f6 E5 D4 a- 谈谈spring对DAO的支持
Q! M2 Q+ ?& Y5 g# t- W+ t' ~$ ^% n1 B& U; Y
Spring提供的DAO(数据访问对象)支持主要的目的是便于以标准的方式使用不同的数据访问技术。
+ i# e; G5 N0 R; j0 `' J6 C7 F 简化 DAO 组件的开发。
. W+ M9 }, n- H3 Y0 wSpring提供了一套抽象DAO类供你扩展。这些抽象类提供了一些方法,用来简化代码开发。2 r& B- X/ _5 w9 R% p" E
IoC 容器的使用,提供了 DAO 组件与业务逻辑组件之间的解耦。所有的 DAO 组件,都由容器负责注入到业务逻辑组件中,其业务组件无须关心 DAO 组件的实现。
2 t- x9 X9 A3 ?- b# p; H 面向接口编程及 DAO 模式的使用,提高了系统组件之间的解耦,降低了系统重构的成本。0 F: Z9 N; ^4 i7 k& P6 ?
方便的事务管理: Spring的声明式事务管理力度是方法级。0 h$ {, [0 a: D/ o! u
异常包装:Spring能够包装Hibernate异常,把它们从CheckedException变为RuntimeException; 开发者可选择在恰当的层处理数据中不可恢复的异常,从而避免烦琐的 catch/throw 及异常声明。& x! l$ v' k2 `5 |
- y' |1 W5 m, h2 o
: g$ f6 _; f% a7 U [% u$ X- B
- 谈谈spring对hibernate的支持9 E4 r8 Q j# [3 Q8 y" l0 c
; j: F' M8 W5 E4 I6 B$ B$ x
在所有的 ORM 框架中, Sping 对 Hibernate 的支持最好。如 SessionFactory 的注入、HibernateTemplate 的简化操作及 DAO 支持等。另外, Spring 还提供了统一的异常体系及声明式事务管理等。
1 ^" _$ M) e M4 F 一旦 Hibernate 处于 Spring 的管理下, Hibernate 所需要的基础资源,都由 Spring 提供注入。Hibernate 创建 SessionFactory 必需的 DataSource ,执行持久化必需的 Session 及持久层访问必需的事务控制等,这些原本必须通过代码控制的逻辑,都将由Spring 接管 ataSource, SessionFactory, TransactionManager等,都将作为 Spring 容器中的 bean。将这些bean 放在配置文件中管理。
; m3 Q+ p8 Q U9 Z 1、通用的资源管理: Spring 的 ApplicationContext 能管理 SessionFactory,使得配置值很容易被管理和修改,无须使用Hibernate 的配置文件。详细配置如下:6 G5 | `, S& F
1 J$ ?# L( ~( }9 u class=“org.apache.commons.dbcp.BasicDataSource”>: H V4 }5 T7 x3 g" V
/ I6 H$ h5 X. f% m" b6 T
oracle.jdbc.driver.OracleDriver5 r% }! A% Q. b) n' V# W, U5 v+ }4 X
' ?2 B& i. e: y8 y# J/ _4 s
5 t: ?+ L/ I# x jdbc racle:thin localhost:1521 rcl
4 J1 o9 u: x# V# M9 Y# ~$ K % }" X; r7 P! E- W n2 p. h, {
: D1 Q, G- ?+ m javakc22 Y' q$ A9 Q3 ]8 i' w
4 x" g! F3 V2 z/ ^2 w& a* f$ J( @6 S, F ' M) F" J3 W* E( e. m
javakc29 i. T9 L5 M' K: y( v
5 D, A4 T5 H* e k, h! M0 x ) J% w5 e3 B8 T
2 A; m+ p3 [+ p& B6 C8 N. Z class=“org.springframework.orm.hibernate3.LocalSessionFactoryBean”>% H; S* H. ]2 B8 L P# A
5 ^9 ~3 o# S3 L4 [0 q% j6 | & d# M, B$ r$ h# Y; H9 r8 B
1 A* U9 l0 G0 G7 ^# ` com/javakc/spring/h3/UserModel.hbm.xml* v; ^# s$ B' [, d7 f2 F& T9 U
. P+ m) \; Z8 L
8 X8 Z! g0 M! g5 M * @1 r* S8 k6 K- c+ x% h9 \2 R- E1 ^
1 S" Z1 X6 g) \$ C L& o" T
hibernate.dialect=org.hibernate.dialect.OracleDialect
% n! o: N9 W2 o' c: n2 s / @8 y& h* H. e7 i" N
7 ]6 X- q8 F' n# Y4 Y" d- D& f# a + q/ y( J, T: x0 ^$ T2 \
/ V6 `8 l1 {% M- \) S4 p # v! m" ?' L, b/ I
; M3 H) ^4 x8 f( Q) M* |
如果需要使用容器管理的数据源,则无须提供数据驱动等信息,只需要提供数据源的JNDI 即可。对上文的SessionFactory只需将dataSource的配置替换成 JNDI 数据源,并将原有的 myDataSource Bean 替换成如下所示: class=“org.springframework.jndi.JndiObjectFactoryBean”>
. A% K6 e2 I& a6 B9 Q " i! o: P, A- G& i% m+ X9 q
java:comp/env/jdbc/myds
4 ^% S" Y- E+ V- `( `8 _: P 6 S( @) N. Q9 o3 u* Q
2、有效的 Session 管理: Dao类继承HibernateDaoSurport后,Spring 提供了 HibernateTemplate,用于持久层访问,该模板类无须显示打开 Session及关闭 Session。它只要获得 SessionFactory 的引用,将可以智能打开 Session,并在持久化访问结束后关闭 Session ,程序开发只需完成持久层逻辑,通用的操作则由HibernateTemplate 完成。 3、统一的事务管理。无论是编程式事务,还是声明式事务, Spring 都提供一致的编程模型,无须烦琐的开始事务、显式提交及回滚。 建议使用声明式事务管理,Spring 的声明式事务以 Spring 的 AOP 为基础。可将事务管理逻辑与代码分离。代码中无须实现任何事务逻辑,程序开发者可以更专注于业务逻辑的实现。声明式事务不与任何事务策略藕合,采用声明式事务可以方便地在全局事务和局部事务之间切换。 Spring声明性事务有两种配置方法,一种是xml配置:
$ I B8 d6 {. |" h U+ h/ [# R/ z
; ^/ L1 ~ `$ F6 F: {" o1 b* ^. o$ U6 b
: T; u. `' W" p- ~* |9 x" F% L * F1 r3 \3 M& e) Q- N4 x
, o: X6 @+ L3 r( u3 i
+ ?1 w. }& M0 [' ~% S
# h1 i+ E6 h. J8 z 4 t# N& f& \) G) c W4 o
- l5 F- f/ Y' B/ m4 M
; W6 J& {- C+ z1 C$ d7 g$ o
& H& W3 p' _/ b$ t! ? . ~; X0 s s$ z# z3 @: e+ F4 t. o
6 K& Z! X, `% h
& n1 N) p# p4 a" a+ o; G8 ` 另一种是通过注解,在需要添加事务的类上注明 @Transactional
! t4 x1 a. N- t2 H: F6 X: NSpring2.0之前事务的写法
6 V/ E4 |5 s( H% L, } y4 T' I/ \4 ]) ^$ d
' H' I& ] }7 I3 S7 s9 g class=”org.springframework.transaction.interceptor.TransactionProxyFactoryBean”0 \. @$ S+ `1 ?3 S- R8 ~
@6 ]6 H( X. u. Q5 r# s. F v! @ abstract=”true”>% F+ ~7 o7 p# h3 b
5 Q( `6 s7 H ^! R3 L" g$ x
8 K$ E. o N3 @9 b+ U# s* G
9 n9 b9 V0 G( {" R
- p( d% ]5 Q/ x PROPAGATION_REQUIRED,readOnly! j$ Q1 @3 O0 j/ R
|3 w& y- l6 ] n
PROPAGATION_REQUIRED# Z* W% f; H. p9 X
: i6 a+ U R8 A1 X/ x
3 J1 t6 S: C4 n0 {# D7 ~" ?; U8 i: Q N) K
) R4 Y' s# g6 i+ G4 b
| ; V5 W5 _' }- F! H
/ U4 a4 _- m$ F$ w
- 谈谈Spring对事务的支持% {+ K# B' p' |3 G+ M1 v
9 v: c# g8 n6 A( q0 X i, }7 s
1 l: D2 q. n3 G: G
1、声明式事务管理: 1.流程:由客户端访问—-aop监控—-调用advice来追加事务 2.做法: 2.1 在配置文件的头中引入xmlns:tx 和schema的文件 2.2 2.3 注入数据源 / L: s3 p- \6 y: z6 W
" ]! m. t }" z5 s* v
& N. a4 ~& C/ F4 ~
% s/ C! F9 ~/ g: \/ L! m' @
9 `5 H0 E& D% ^% e* E) i7 ~5 |$ w1 {9 ~4 C( y" Q4 j
2.4 由spring实现的事务管理,但需要注入数据源 2 ]4 Q8 w6 E7 R2 F+ V) ?
1 s H/ a) o: v; }1 P# i+ s( L, t" J0 ^+ D X3 ]% `
2.5 事务监控所有的方法(事务加强)
* d, I% F, X" S2 ^2 W2 g8 [+ R0 m- T8 ]' H7 ~( l0 c
6 `$ n* H3 Q2 C$ U8 Z i# Y
' R$ M. {+ L. q6 B H$ S' h; }
$ M0 D* I' g+ K; {" l0 U9 b; ^2.6 定义切入点 1 P% m4 u, i* ]( D
& g# }0 H" m9 t& H7 y3 Q
8 b/ D0 y! \7 t- _# X. n
# A! E7 [( x, R r. }$ U' u! S9 B% J/ e4 z, s* O1 I: F
2、使用注解实现事务管理: 1.注解@Transcational (可以在类上,也可以在方法上) 2.在配置文件中同样需要注入dataSource和spring的事务管理 3.使用注解的方法来追加事务 注解驱动 + t* c# w: s* r N' z6 d, A
* s7 J. v. Z7 T9 V$ z+ X: ^ J: [
如何在Spring中使用Hibernate的事务:$ o% E' ?3 F, ^; @/ K, u r! f
- n/ L( ?5 u# d
7 l! G1 l% }8 ?4 V - q( _2 `; `0 m5 F0 `! V- o6 H
如何在Spring中使用JTA的事务:
- Q$ h) G% V9 Y : W4 X1 ]6 \/ C0 C: i0 @' i
|