Spring6 f3 i$ y9 y: L% u* I* W
- 是什么?- w2 r: y# K; f4 s3 h. [ C9 _9 C
2 i7 T7 o# F% ^
Spring是基于JEE的轻量级的应用框架
, n/ [- R/ O0 }* G! I) I- 有什么?
9 k: J, V% b% v6 J4 ]6 d1 j$ F( @& x7 @3 }
6 C+ R& p- m0 t0 w# o& S
每个包的功能: Spring MVC:spring 本身提供的web 框架 WEB:集成其他的web 应用的框架,或者说是对其他web应用框架的支持。如struts,webwork JEE :集成一系列的jee的技术(对JEE技术的支持) DAO:封装了JDBC;(对JDBC的支持) ORM:提供了对ORM工具的集成(支持) AOP :面向切面编成 CORE:spring的核心包,提供bean的工厂和IOC容器 1 [5 g4 I. s7 @" m
- 能干什么?
/ L# _" p0 L; W: k" [, M
) g5 u5 V E/ u$ A# _
把一系列的jee的技术有效的组合在一起形成以良好的系统 $ r; N$ l/ c( L' G7 m
- 怎么用?7 a$ U2 _6 d6 ?* V) H- I
7 ?" K% \4 n: p2 l+ d) R- 搭建web工程,引入spring的jar包
: i+ V0 G* S: J* f% }6 z/ M- k - 在web.xml中添加如下配置/ u0 C+ W! |6 n) ~7 j
* ?0 H" ^7 Z8 Y- j/ h7 E7 L 9 ^( v1 J! V) Y5 c( Q$ _
( @* X8 T5 R) j9 u5 X( \3 Q
contextConfigLocation& |2 u3 C# t% e# F4 @, C
classpath*:applicationContext*.xml
; k; Q) P: d1 o$ @
$ z0 O! z+ j; S; \$ R 4 ?5 G! e" A. V, S1 _: V
struts2
- ^6 ^2 n1 V4 P+ O- t$ ]9 v @
8 j1 n5 B7 o! S) \3 G% a# z org.apache.struts2.dispatcher.FilterDispatcher
- y7 U7 V. h; v; k G1 g" n# r; o* p. w; S) t
+ y/ w z! J0 b3 Y& H' b
" F) S' u$ u) {1 l3 a" T; ? struts2
2 D6 F y6 f- W' |5 u /*
* A- w9 I% u/ x. l& F3 s- T& A & D1 \7 k }% Z$ V7 S) H, ^
5 J5 h8 q' j: i
: c5 {4 {3 f: \, [) T
org.springframework.web.context.ContextLoaderListener
8 N) H% x1 X8 B
, _% f) r- l& K. f* l+ _ C) | - 部署' T3 k$ J, x2 x" D- }: `/ z
0 w2 P7 x) A; k4 t% w 9 {0 r- p$ x9 m0 e m: G* R/ p% e
. v+ [/ L; E# ~5 H" F" h3 N4 ~$ N9 E
5 [5 M3 ^9 O& T9 ]2 Y/ e8 o2 J- 容器和bean/ a6 |; p! ~* N( D, L
Bean :是指受spring的ioc管理的对象称为bean 容器 :(与jee的容器类比) Jee :提供组件的运行环境和管理组件的生命周期(不能单独存在) Spring :提供bean的运行环境和管理bean的生命周期(可以单独存在)
: |0 n- v7 c. c ?
9 b" J$ D2 O) J# w6 P# j- DI依赖注入; b, {6 u, ^5 P: p! X; L2 `
1. 应用程序依赖spring注入所需要的对象 IOC和DI是对同一种事情的不同描述 2.setter注入: 在配置文件中将接口的实现配置为bean在应用程序中注入bean 例如: 在配置文件中
4 T9 U# f8 }0 y' R! i2 G! S4 }' t
% m( ?9 }! P/ @" D+ z0 m, X5 `% y
' O: N) p8 a( F/ l3 w4 Z( G在应用程序中 Public DBDAO dao ; Public void setDao(DBDAO dao){ This.dao = dao; } 3.构造器注入
0 ?# x' k) K5 w8 S3 f2 S4 @4.ref 表示参照其它的bean 在参照的过程中一定要注意死循环 5.自动装配———–〉no 自动装配根据名字来匹配相应的bean 尽量不要去自动装配 6.lookup注入 7.singleton 1.单例模式是整个的jvm中只有一个实例 2.spring的singleton是指在spring的容器中只有一个实例 一个生命周期中只有一个实例 8.DI的优点: 1.程序被动等待,强化面向接口编成 2.切断了对象或组件之间的联系,使程序的结构更加松散,运行和维护更加简单 & d0 M" p- Z, Q5 ^
- Aop面向切面编程% ~( }! ]+ a! n/ ^
/ y& ]* F& u3 v7 @
1.AOP面向切面编程 一些较好的模式或者是示例—-范式
) y) i! T D- X- d 切面:一个切面代表我们所关注的一系列的共同的功能点(模块之间的共同的功能点) 2.AOP的思想: 主动—->被动(追加功能)
! T1 v4 k6 w8 @4 R6 ? 3.AOP 的概念
* v4 b! c, b* ], _0 @- }- Q% M" {$ N7 T 1.切面 :我们所关注的功能点 2.连接点 :事件的触发点(方法的执行) 3.通知 :连接点触发时执行的动作(方法) 4.切入点 :一系列的连接点的集合 (连接点的模块化) 5.引入 :扩展的功能 6.目标对象 :包含连接点的对象 7.aop代理 :实现机制 8.织入 :把advice和目标对象连接起来 4.AOP的事件机制+ j/ @8 T. b$ k
1.通过切面找出一系列共同的功能点 2.找到目标对象(在标准的spring 中 接口的实现类为target) 3.找到切入点 4.确定连接点 5.通知spring AOP,查询xml文件,通过代理找到advice。 6.由aop代理来实现动态织入
& Z, K" j0 h( ?( R b# o; N9 X0 ], }7 w/ f6 M( w& e
$ K2 C( F% \* k5 p4 m `
: h& Y; s Z* O( k6 A8 {' R
+ F- ?- Z( @6 g1 S: I9 w7 }
# ?$ h; p' {8 p; b, j
* S' v; r8 B; q# E8 X: W5. AspectJ
& x9 Z1 `- u2 }9 L/ L- C+ N: w 5.1.在xml中配置比较烦琐
- P+ I" C% M4 @! w/ B 所有的入口必须从一个代理(ProxyFactoryBean)开始" V& h1 C2 ?# U9 ]$ ]
6 R! ^; \7 J: x6 m
% u% F7 c" |/ B9 P; ^& l
. R5 k* k8 y" Y( w6 E
6 u8 i1 U1 B) h, f5 a) ]+ T
0 p- [3 t' N+ B9 ?: `5 B% }
5 `/ o' n' W; w/ t - [0 f# U0 b4 s
- [# C0 f, h2 l3 t6 D
expression=“execution(* com.javakc.aop.MyTarget.t*())”/>
$ E2 V d: ], w7 t
% G% b7 I) Y; A0 j+ H8 A( f / n/ v& W! B( B* l% @
1 E; @: N2 d+ u" u - h. l% R$ q: q# ]) s
& O8 B9 }3 R9 Y, C# a5.3.使用注解的方法相对简单% J9 J$ N8 T9 d% o8 A, {
@AspectJ的基本语法9 T, V( f7 Q8 n- T+ w
1.@Aspect声明一个切面,将一系列的共同的功能定义成一个切面
9 j( g$ k! o/ Y! Y 直接在类上定义@Aspect& y3 T5 S: j {6 p1 O4 G
2.@Pointcut声明切入点4 { J) s9 M5 t) `. ~
2.1、用一个专门的类来定义pointcut,类中的方法名就是该pointcut的名字
2 g5 o+ a4 Y8 n! f 2.2、可以使用匿名的pointcut9 b& a# y( F0 ^. ]% N" _7 I
2.3、执行切点的几种方法
* F b8 J% p! l# y- i' D% k 2.3.1 execute(public * 包结构.*.*.(..)) 可以指定到具体的方法# n, ^6 w2 N" g$ |
2.3.2 within 指定到包,不能指定到类8 l) L3 C* g s1 v. ~
within(”com.javakc.spring..*”)3 D% u/ H G" I* g
2.3.3 this 指定到实现接口的所有的实现类
4 ?2 Y$ E; {7 @# b: t! U 2.3.4 target 指定具体的实现类
, B4 I' ]- g* r f1 f1 e 5.4.advice的五种类型的示例
: v6 w( h1 b! x# w( d% s' W$ J' Z 客户端必须从接口走才能得到监控,实现想要追加的功能1 Y. V0 y5 l6 i+ O2 m( g9 A& r# W
5.4.1.@AfterReturning(pointcut=”” returning=”retVal”); A* j1 G9 R( Y0 w# O2 o0 o0 H' r
追加的方法的参数名字一定要与retrning的名字相同
4 \2 T& e# `1 Q! f& {' ] 在注解@AfterReturning中必须加上pointcut和returning两个参数! N) [6 W; U( |# X2 o
pointcut指所要监控的目标对象的方法
: u; r" j, S5 T5 f8 d; ]5 Z; H 得到目标对象的方法的返回值,来作为参数,进行下一步的处理,参数没有顺序,按参数的名字进行匹配. v; y2 P8 b5 R
完成追加的功能
' `5 r7 p1 Q+ _6 h8 W 1 定义一个pointcut,通过方法名来作为pointcut的名称来引用5 K3 M$ _5 `+ k: e* b# U
(1).@AfterReturning(“com.javakc.spring.schemaaop.TestPointcut.t4()”)9 f p# Z* S2 G7 d
(2). G! Z+ w' X* H
2.直接引用匿名的pointcut* c( }1 l4 B! F' e
(1).@AfterReturning(“execution(
" {( r# M2 F, W * com.javakc.spring.schemaaop.Api.test4())”)
2 u6 r8 g) t, P+ [6 C2 x (2).@AfterReturning(pointcut=
. T" x5 n% u* P& K$ e5 _ “com.javakc.spring.schemaaop.TestPointcut.t4() &&
* b7 f1 G& u9 j" @ args(str)”, returning=”retVal”)
. X# t6 A% d# N: s @AfterReturning (pointcut=”com.javakc.spring.schemaaop.TestPointcut.t4() && args(str)”,returning=”retVal”)
- K* v4 b% }( [' J public void testAfterReturning(String str,Object retVal){
6 O- p5 O3 ], R& G: x) h' o! s System.out.println(“afterReturning1=>”+retVal+”=>”+str);
6 M! j5 K0 U" |6 r }# P) m5 Z0 t9 t) ]( Z: M
5.4.2.@Aronud* Q: X+ U, r# [* E/ G; M* _
注解@Around环绕追加功能;
# y, G" {* G" h B 在执行目标对象的方法的前、后追加功能;4 M _3 p1 @8 d. ?7 C8 z
必须有参数;第一个参数的类型必须为ProceedingJoinPoint;$ K8 P# d6 u- w$ p; M+ v+ h
通过ProceedingJoinPoint的实例的proceed来调用所监控的
9 N4 N0 L6 P% I* H) x" G2 L1 \ 目标对象的方法
5 P) g3 b2 ~+ m9 I 1 定义一个pointcut,通过方法名来作为pointcut的名称来引用$ ]. t& K+ D0 @9 {' V( q7 ^
(1).@Around(“com.javakc.spring.schemaaop.TestPointcut.t1()”)
* {1 q' x, [3 `- U7 W2 w (2).@Around(“com.javakc.spring.schemaaop.TestPointcut.t2()3 f* e9 D2 i5 u4 c6 v
&& args(str)”)
, m; i6 b3 a6 G 2.直接引用匿名的pointcut
- i5 |# u+ ^6 K; o/ m* m% t" | (1).@Around(“execution(
( q% [* \4 ^7 f * com.javakc.spring.schemaaop.Api.test1())”)
9 J: }1 V v1 q! `) P) n* M (2).@Around(“execution(& r4 d4 V, R( R* t2 E
* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)
O* D" T3 ]" p& @- J, K) { // @Around(“com.javakc.spring.schemaaop.TestPointcut.t2() && args(str)”)# r* @- e# C$ N, f2 {
@Around(“execution(* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)
! E, n6 y) z( Z( `8 j1 n/ C public void testAround(ProceedingJoinPoint prj,String str) throws Throwable{
/ h: ]0 W( m& s# [$ k5 M! C } System.out.println(“around1==========before1pointcut==>”+str)/ w: K. y1 a; [% ^/ d- S5 z/ t0 N
Object obj = prj.proceed();! G4 ]$ X5 h- f8 m7 w7 H
System.out.println(“around1==========after1pointcut==>”+str);) q, g4 o) {; J; M3 u9 R6 t* t
}+ V# z% V- q( i9 |, Y% N; Q
5.4.3.@Before
( C) p4 L+ S, ?; r3 |+ m" a 注解@Before在执行目标对象的方法前追加相应的功能
) a4 e; J1 A: Z 1 定义一个pointcut,通过方法名来作为pointcut的名称来引用8 h- R, ^ I' f0 G! w
(1).@Before(“com.javakc.spring.schemaaop.TestPointcut.t1()”)" q( [& u, f- d
(2).@Before(“com.javakc.spring.schemaaop.TestPointcut.t2() && args(str)”) R8 U7 L2 E' V/ R4 I& t
注意args后的名称与参数名相同
; P7 k. K. Y- ? q F 2.直接引用匿名的pointcut. E- C4 @0 @* H: x) Q6 \
(1).@Before(“execution(* com.javakc.spring.schemaaop.Api.test1())”)
( V* T, P- I# R( f; t (2).@Before(“execution(* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)$ o# I( j$ S$ W- w7 U. h
注意args后的名称与参数名相同+ |8 k* ?/ F0 r
// @Before(“com.javakc.spring.schemaaop.TestPointcut.t2() && args(str)”) D" ^7 \0 U- R( u/ p& y8 G* @
@Before(“execution(* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)
0 s$ M4 r; e' S3 ~( N8 D public void testBeforeParam(String str){' k6 e' I$ T; t a% e( m0 O
System.out.println(“before1=param=>”+str);
5 a4 E. \8 X5 p* f! f1 L* n# I6 r }, O7 @! }$ \4 `
; f: d" j+ [0 I2 H2 S0 N c+ Y5.4.4.@After" @. J4 I7 L7 p" i9 @) E
注解@After在执行目标对象的方法后追加相应的功能
6 d7 W5 Z: l2 S3 R$ H8 J1 b: w 1 定义一个pointcut,通过方法名来作为pointcut的名称来引用
$ H( v/ u" K9 v (1).@After(“com.javakc.spring.schemaaop.TestPointcut.t1()”)# W1 W# X3 ?7 D p
2.直接引用匿名的pointcut
# z% {% s" ^ c( E/ ?: v8 Q (1).@After(“execution(* com.javakc.spring.schemaaop.Api.test1())”): e2 w3 u* _$ ?9 n+ |7 Z
@After(“com.javakc.spring.schemaaop.TestPointcut.t1()”)( j2 G8 I$ x% M# q i3 S' Y
public void testAfter(){0 O. I1 H2 B6 C& Z! {
System.out.println(“after1== >pointcut”);
+ W7 A$ [# g3 _* f }
# g8 B& |# S& C( a! X. j1 z 5.4.5.@AfterThorwing
) y0 d+ R. \) r) T( l ' x( P4 `4 c$ E" B6 J
0 M6 A L0 Z7 U- y5 F) u- i) s% e6 O( I
- 描述一下spring中BeanFactory和ApplicationContext的差别
1 U7 M( H' ^1 _5 r; V7 S3 t7 L) S/ C' v( D) X/ P7 R
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”); 8 `8 |( z- O; X" ~; R P7 @. F2 l
- 谈谈spring对DAO的支持2 R Q! f2 `5 }. n
3 `% v# m& O& H
Spring提供的DAO(数据访问对象)支持主要的目的是便于以标准的方式使用不同的数据访问技术。
6 ^' X, J( O- g9 A0 D* R7 Y 简化 DAO 组件的开发。
1 w" y+ W$ R8 e' q% I+ @- RSpring提供了一套抽象DAO类供你扩展。这些抽象类提供了一些方法,用来简化代码开发。* ^) b+ }, i/ _$ t g% |) l; u5 r% T
IoC 容器的使用,提供了 DAO 组件与业务逻辑组件之间的解耦。所有的 DAO 组件,都由容器负责注入到业务逻辑组件中,其业务组件无须关心 DAO 组件的实现。& C0 n; l& t. w( M! W+ ]3 _
面向接口编程及 DAO 模式的使用,提高了系统组件之间的解耦,降低了系统重构的成本。7 v0 s( b6 F; h6 b' ^# w% s5 |8 H
方便的事务管理: Spring的声明式事务管理力度是方法级。# |7 A$ P8 R6 ~( I+ H, f
异常包装:Spring能够包装Hibernate异常,把它们从CheckedException变为RuntimeException; 开发者可选择在恰当的层处理数据中不可恢复的异常,从而避免烦琐的 catch/throw 及异常声明。
: z, h7 Y1 O8 N+ J# w: C m
B- \- ?4 }- X- g1 m% t, l$ q/ k8 c% ^
- 谈谈spring对hibernate的支持+ C5 O% q8 A8 x* O
' P( G. p# @( c3 f$ m
在所有的 ORM 框架中, Sping 对 Hibernate 的支持最好。如 SessionFactory 的注入、HibernateTemplate 的简化操作及 DAO 支持等。另外, Spring 还提供了统一的异常体系及声明式事务管理等。
" h7 s, K, n8 [8 W 一旦 Hibernate 处于 Spring 的管理下, Hibernate 所需要的基础资源,都由 Spring 提供注入。Hibernate 创建 SessionFactory 必需的 DataSource ,执行持久化必需的 Session 及持久层访问必需的事务控制等,这些原本必须通过代码控制的逻辑,都将由Spring 接管 ataSource, SessionFactory, TransactionManager等,都将作为 Spring 容器中的 bean。将这些bean 放在配置文件中管理。
$ n' f' r' ~$ a7 e [$ w+ j 1、通用的资源管理: Spring 的 ApplicationContext 能管理 SessionFactory,使得配置值很容易被管理和修改,无须使用Hibernate 的配置文件。详细配置如下:
3 j* g0 [ g3 J3 {% j4 r6 x$ r# O 0 C( p0 o0 V2 V4 t( Y# }8 W: Z/ B
class=“org.apache.commons.dbcp.BasicDataSource”># ^9 v4 r5 l: l- ~4 r4 A$ j
4 y; s5 h3 y9 {7 i* \+ P" l" ?
oracle.jdbc.driver.OracleDriver
* v I! [$ e. K0 F: w2 b / h# g/ w( n- k8 P& C1 S9 y" x
; N1 t; w% {8 }# ^9 `) S) r
jdbc racle:thin localhost:1521 rcl2 W* Y: j/ E' t* ^; k* g
+ H" A2 i- D9 t' }* r) R
7 p+ i( L! S+ ^, E }, @: E javakc2
) G$ N0 C3 V; x& g9 v * L. e$ [4 R/ N
. X6 s2 }4 |* O" r$ E javakc2+ \+ R2 {- X# A3 d: r ^% E5 c# v
7 K: U% ^+ @" B+ C) T* \' h$ t
3 X8 W |& }( n. I2 S 3 a, I1 o7 W! q. i( ]
class=“org.springframework.orm.hibernate3.LocalSessionFactoryBean”>
) \* U2 M1 f. K5 Y
1 ?0 g8 k4 k) a! G" [
8 L6 p7 A3 ]) c# }
! M1 w* u6 I6 L! Z* G V4 _ com/javakc/spring/h3/UserModel.hbm.xml
A: ^% A& A) t9 W- \0 U
& ?6 W+ }% W+ H- C& [, l
. \- D, k1 z4 }& O! w. @
& A1 @2 P9 i' j* o
) \0 Y; K V5 }+ P* f hibernate.dialect=org.hibernate.dialect.OracleDialect
) ? F8 Y; }/ D, T+ h% f3 a; s
; S8 ?0 V2 @1 G* D
3 ~6 h" ?' e: M2 \% O. @ 4 F6 C4 s$ f( d; a7 g8 a
; ?8 c# m) m( e6 l2 R( ]( B
8 o0 s$ v' T. ?" @7 Z3 l0 A5 a
, X2 J6 Q7 ?# m7 R; F( P& _+ o
如果需要使用容器管理的数据源,则无须提供数据驱动等信息,只需要提供数据源的JNDI 即可。对上文的SessionFactory只需将dataSource的配置替换成 JNDI 数据源,并将原有的 myDataSource Bean 替换成如下所示: class=“org.springframework.jndi.JndiObjectFactoryBean”>
- R, f+ [2 R$ i2 \- | 9 H0 f7 H+ t9 Z' L
java:comp/env/jdbc/myds
" C, z/ O) l. q7 _' P 8 v, O: p: i* [) L- j- F
2、有效的 Session 管理: Dao类继承HibernateDaoSurport后,Spring 提供了 HibernateTemplate,用于持久层访问,该模板类无须显示打开 Session及关闭 Session。它只要获得 SessionFactory 的引用,将可以智能打开 Session,并在持久化访问结束后关闭 Session ,程序开发只需完成持久层逻辑,通用的操作则由HibernateTemplate 完成。 3、统一的事务管理。无论是编程式事务,还是声明式事务, Spring 都提供一致的编程模型,无须烦琐的开始事务、显式提交及回滚。 建议使用声明式事务管理,Spring 的声明式事务以 Spring 的 AOP 为基础。可将事务管理逻辑与代码分离。代码中无须实现任何事务逻辑,程序开发者可以更专注于业务逻辑的实现。声明式事务不与任何事务策略藕合,采用声明式事务可以方便地在全局事务和局部事务之间切换。 Spring声明性事务有两种配置方法,一种是xml配置:
5 O" M; S2 D# Z4 d) s 8 u9 b* D6 K( k8 _
' C7 t b( c2 ]5 [) V, P
+ A; M6 C6 J' P% B) J
8 S6 U" `! o+ f/ R8 u4 A * `$ ^0 U( a. ]* y
) d( h9 u9 a6 K/ O) c* m, R2 M. j 3 { r% y8 H6 n6 Q; m/ }
) S8 H; }$ I' f
3 x4 S4 W1 O# a3 G0 I5 _/ n- ]
8 M7 S4 k+ r. ~ 1 b: ]) Y) S& C2 b) C
' J! R5 A3 D& r) M2 G8 T / P, o0 A. H8 p) H8 x+ n2 {( g7 k
另一种是通过注解,在需要添加事务的类上注明 @Transactional ' u5 C m6 Y8 q3 e, [( w- @
Spring2.0之前事务的写法5 r1 Z0 \4 c& Y% l
& @# F3 J, r2 g, ?' s) K
4 F7 R j8 j! f' K! c. K class=”org.springframework.transaction.interceptor.TransactionProxyFactoryBean”
8 B+ M. H# s. q+ g+ r% D, _( o1 R4 _3 L( ^
abstract=”true”>3 U3 W4 F# r1 e! `
' E% F7 J. p% [) ^0 y, U
3 ^8 K( ], X) d! M8 E4 g8 B
1 r2 i/ v8 v& z3 u7 {1 f( v/ E# Z8 o) `2 H
PROPAGATION_REQUIRED,readOnly
6 P8 b) f' p0 I7 D, Q: N+ \* D$ j' G$ W5 w% [' r
PROPAGATION_REQUIRED
, ?) m- G' b7 y$ j I7 t: [
; T, x* U6 X' G' m+ X' s- Q; t' @+ n
; X$ v4 c' D6 f$ C: D* ~5 ]% g& q3 x7 C$ v' B! X8 A9 U
| x* W) {5 V$ S
6 m0 f' j$ ^6 ^
- 谈谈Spring对事务的支持
5 j0 t/ U7 |8 O# h& ~* O+ G
$ s# f" f; I3 W. f
4 _5 }* t$ q0 m! ~ O i. S1、声明式事务管理:
1.流程:由客户端访问—-aop监控—-调用advice来追加事务 2.做法: 2.1 在配置文件的头中引入xmlns:tx 和schema的文件 2.2 2.3 注入数据源
( L7 \* t, ^) F1 i; E
) x) R6 U0 \; Y- t/ K$ }& y
5 g& ~% P4 n' o4 w6 y6 A1 ?+ T0 S( p" j2 o% C! X; ?
7 @+ I; u- m" z5 Z. E! r) S
) U: T6 Z- ?6 x
2.4 由spring实现的事务管理,但需要注入数据源 $ V, c$ c& O" [
" u6 _. d. m% W8 I0 |+ N8 n$ P
6 l! |3 w! @4 k7 t2.5 事务监控所有的方法(事务加强)
1 s" V3 K7 w/ b2 _" v0 e8 R H! \0 g( c& h
% W5 x4 R5 l0 |* w) `8 I, a! D' @& a. r, f
8 e9 h5 D% X$ G. `
2.6 定义切入点 $ V9 |- Z0 a" I- [4 {
% s. {1 @' Y5 ^
( k# S% F6 {( c6 p, {/ I2 P( _$ d- e: w; E4 G/ B/ Z! l, ]
; A5 y5 H; C! [" n e$ j8 |% e+ P
2、使用注解实现事务管理: 1.注解@Transcational (可以在类上,也可以在方法上) 2.在配置文件中同样需要注入dataSource和spring的事务管理 3.使用注解的方法来追加事务 注解驱动
, J r# D/ i3 M3 C
. ]3 p2 w3 G1 n; m" N$ J) C, J, Y如何在Spring中使用Hibernate的事务:6 F5 K" m& b) M
8 d& J3 a- l: a8 l3 O V% c
( O1 Y5 L9 z8 i% T
" M' d4 V0 l4 d' Y6 v" x2 e如何在Spring中使用JTA的事务:6 N; Z) U1 `7 h6 A; V4 x `$ Y
, S0 J9 E% A& B4 L1 I
|