Spring4 x Y8 Z. H |: G
- 是什么?
4 i( i2 o! q1 m3 S" b5 `, c& u" {1 x
Spring是基于JEE的轻量级的应用框架 . x$ C- K* J( }
- 有什么?; g# G$ ^* d$ C
* N8 A) a- l' m# j# v# a; ~
3 r. k* u3 ^0 q5 O8 H1 G
每个包的功能: Spring MVC:spring 本身提供的web 框架 WEB:集成其他的web 应用的框架,或者说是对其他web应用框架的支持。如struts,webwork JEE :集成一系列的jee的技术(对JEE技术的支持) DAO:封装了JDBC;(对JDBC的支持) ORM:提供了对ORM工具的集成(支持) AOP :面向切面编成 CORE:spring的核心包,提供bean的工厂和IOC容器 # K! }9 L8 F) p/ M# j3 e
- 能干什么?
7 q$ K( I! c3 [4 ]5 b
) ^( ^; U& M* I, G
把一系列的jee的技术有效的组合在一起形成以良好的系统
/ ?6 l* i. B' j/ p& B/ z% T- 怎么用?# X `* C* T. D3 `# z) Q8 r% d
' L, ]0 X% H7 P" ]9 }4 g4 O- 搭建web工程,引入spring的jar包/ T2 E$ y- R" l' H; ? w/ t
- 在web.xml中添加如下配置+ v8 s! ~ G: ^) Z9 A: D
c" ~: b5 L9 N9 d- t% ~0 j
_: e* p; R6 {2 j* d6 `
$ y6 ^2 o" W, _! W& c
contextConfigLocation# Q. y$ \# L0 i1 ^
classpath*:applicationContext*.xml
5 h k, K% o+ r4 Q, B9 Z
( ~1 a* y& |* ^$ w3 i7 @ , b( O; Z5 Y& y; b. a) y- N
struts22 w8 f+ u% Z8 Y* `
* C6 d( ?& z, ]9 }& @ org.apache.struts2.dispatcher.FilterDispatcher
3 c% ]: ?2 b# I9 d) @ 6 J* i J" I$ F5 t9 }! A
5 X( Z" Q3 p3 P. T% Z
Q1 w% L* t2 y8 X$ }! X struts2& g# J) i6 v: D% N3 a2 Z5 z
/* ~1 n+ c* T$ z& S; D7 _
" c' @$ A7 W. b5 S* P
1 G5 c, h( M1 z
3 ]' f) O& v% b4 m) a$ q% e5 t org.springframework.web.context.ContextLoaderListener' i8 B1 t% T/ D9 i9 [3 T. n
1 w) z6 z' O, W/ U0 B. b* O - 部署
, E# Q/ i4 d. t/ }" d- `# y0 v6 B2 r2 P8 }; w# @
4 C, [, S* `/ o6 [5 f+ V
- S' r7 `# ?) K$ w: r4 _
$ b" w) o, H0 e" W- 容器和bean; l$ k* s/ H- S8 J2 f# t0 Q8 f, e
Bean :是指受spring的ioc管理的对象称为bean 容器 :(与jee的容器类比) Jee :提供组件的运行环境和管理组件的生命周期(不能单独存在) Spring :提供bean的运行环境和管理bean的生命周期(可以单独存在)
. o* g, g- g1 k7 J& `% S
* F4 i6 Z# i6 F/ s' v, {. a1. 应用程序依赖spring注入所需要的对象 IOC和DI是对同一种事情的不同描述 2.setter注入: 在配置文件中将接口的实现配置为bean在应用程序中注入bean 例如: 在配置文件中
. o/ X3 p; X' m7 F+ v$ M% p7 Q. w) m( X, G" O
: [* S3 m" i! b( K! o
在应用程序中 Public DBDAO dao ; Public void setDao(DBDAO dao){ This.dao = dao; } 3.构造器注入 : u' K& T4 Q+ j" O# m" o0 d
4.ref 表示参照其它的bean 在参照的过程中一定要注意死循环 5.自动装配———–〉no 自动装配根据名字来匹配相应的bean 尽量不要去自动装配 6.lookup注入 7.singleton 1.单例模式是整个的jvm中只有一个实例 2.spring的singleton是指在spring的容器中只有一个实例 一个生命周期中只有一个实例 8.DI的优点: 1.程序被动等待,强化面向接口编成 2.切断了对象或组件之间的联系,使程序的结构更加松散,运行和维护更加简单 . h4 b: Q' T& s0 v, I
- Aop面向切面编程
( l% E- F6 P' O# u3 Q: c3 I
. ]* v; b0 o% D6 b D* m9 W
1.AOP面向切面编程 一些较好的模式或者是示例—-范式
7 [; }6 t" s+ ~3 I2 \' v 切面:一个切面代表我们所关注的一系列的共同的功能点(模块之间的共同的功能点) 2.AOP的思想: 主动—->被动(追加功能)
. @8 V- ?- a6 Y' K" m 3.AOP 的概念
- i3 q8 J: L `3 l 1.切面 :我们所关注的功能点 2.连接点 :事件的触发点(方法的执行) 3.通知 :连接点触发时执行的动作(方法) 4.切入点 :一系列的连接点的集合 (连接点的模块化) 5.引入 :扩展的功能 6.目标对象 :包含连接点的对象 7.aop代理 :实现机制 8.织入 :把advice和目标对象连接起来 4.AOP的事件机制
! M9 T5 u/ \6 {& T3 l: A 1.通过切面找出一系列共同的功能点 2.找到目标对象(在标准的spring 中 接口的实现类为target) 3.找到切入点 4.确定连接点 5.通知spring AOP,查询xml文件,通过代理找到advice。 6.由aop代理来实现动态织入
( J' m' t% ]2 ^5 Y
# B, d4 T2 B$ c s1 ~- ?0 {/ w5 O' x8 G4 G7 M
* M! [# P1 l$ q0 R; ?
/ S5 J9 q( j Q- w/ n& l( Y F; f4 S3 u. C+ y! i+ B; l4 S( P/ B
# `; M: p; [* w8 i; W3 p
5. AspectJ
" a- a, ` R( w# a# Q3 P, J& B4 Y 5.1.在xml中配置比较烦琐
; {- C' |5 Y% `, P 所有的入口必须从一个代理(ProxyFactoryBean)开始
# T2 d: |. ?" C) D, x4 d
: Y8 C9 [* _, X7 E& J * Z/ r! M; f- K* m) m& `6 g
9 k6 Y; e( S* ?: q9 ]) _
" j# z& @( N/ a8 v7 Y
4 g: R" a( D$ p1 S- A5 z" x
" c3 }2 a4 Y& b5 l$ d5 W9 {
2 X; ]5 k2 d& U0 j9 l2 v
2 F0 S* U3 O. A( j+ ?6 Kexpression=“execution(* com.javakc.aop.MyTarget.t*())”/>
1 ^+ j! A# y! r* ~6 D- O0 o
% n: X5 E1 v! `. x
# {5 I* k! x$ d) R8 U 6 p6 z. S7 x6 Y+ Y* w
; G' b5 R) v3 k! U8 f$ N
+ H' O7 B$ l" Q5 T# s5 W5.3.使用注解的方法相对简单
" \' B0 Q3 V# K" J @AspectJ的基本语法- N! g j7 Y$ ], {* V3 g, O9 U3 ~
1.@Aspect声明一个切面,将一系列的共同的功能定义成一个切面, _* Q1 L, I( O0 ^& P& a
直接在类上定义@Aspect
' d! N7 `3 \ w6 n0 I* p+ w 2.@Pointcut声明切入点. ? D1 J: M' R9 p y8 r
2.1、用一个专门的类来定义pointcut,类中的方法名就是该pointcut的名字) Y. n+ |% ?. ?6 l
2.2、可以使用匿名的pointcut
7 m7 u9 ?# U _1 Q 2.3、执行切点的几种方法6 d; y- q. [$ O: q, d2 e9 d
2.3.1 execute(public * 包结构.*.*.(..)) 可以指定到具体的方法# ~" E" J. x( C& U" f# ?) B! ]) w
2.3.2 within 指定到包,不能指定到类' L& f- e! P6 B4 d9 M6 B1 D. f5 H
within(”com.javakc.spring..*”)
- Y7 {9 e/ t; f% V$ n1 f0 j 2.3.3 this 指定到实现接口的所有的实现类5 I% e$ g4 W; ~9 [9 U6 \
2.3.4 target 指定具体的实现类
/ Q' I/ S; n, Q3 Q! t- m 5.4.advice的五种类型的示例
0 F9 V& v/ b8 M9 j; ~& Y9 M 客户端必须从接口走才能得到监控,实现想要追加的功能
: ]' l ^4 W6 ^, h% ~, r 5.4.1.@AfterReturning(pointcut=”” returning=”retVal”)5 g/ U3 V! X* I6 f
追加的方法的参数名字一定要与retrning的名字相同' B% j$ ?# u. l& P2 Q( V
在注解@AfterReturning中必须加上pointcut和returning两个参数
" @- j9 V. X) T( \' X4 q pointcut指所要监控的目标对象的方法2 N% |9 U: k5 @" b K7 \; F* |
得到目标对象的方法的返回值,来作为参数,进行下一步的处理,参数没有顺序,按参数的名字进行匹配
1 p% V, K9 j0 U- g. s F0 y# _, \ 完成追加的功能
) y' U$ a% g; T, B! o 1 定义一个pointcut,通过方法名来作为pointcut的名称来引用# g( T: b) }, ]! B ?0 T7 b
(1).@AfterReturning(“com.javakc.spring.schemaaop.TestPointcut.t4()”)
: Z( d3 n8 O( X Y0 ? (2).
0 d: F3 r6 d- m9 Z- U2 S& ] 2.直接引用匿名的pointcut
5 {7 h2 I, q' G- R3 Q! j* v5 Q (1).@AfterReturning(“execution(1 t. k. ^4 u6 @% [
* com.javakc.spring.schemaaop.Api.test4())”)
: g4 e. y2 |3 y! o6 { (2).@AfterReturning(pointcut=
( K( {5 `6 N% z7 ~ “com.javakc.spring.schemaaop.TestPointcut.t4() &&
5 ^0 H; u' F1 W) ?$ L! L8 ]! @) b, d args(str)”, returning=”retVal”)
. h! \! X7 d0 S @AfterReturning (pointcut=”com.javakc.spring.schemaaop.TestPointcut.t4() && args(str)”,returning=”retVal”)
0 d$ I o: Y- S5 M# [ public void testAfterReturning(String str,Object retVal){
' U" f+ F9 Y3 J0 n5 C) j System.out.println(“afterReturning1=>”+retVal+”=>”+str);& [( x: @5 ~ U, _9 e3 d2 q* o
}: e8 j9 |/ I; F4 F8 w
5.4.2.@Aronud1 y) M9 T# q/ K% B! l
注解@Around环绕追加功能;+ g, T8 f" T' O1 w- }
在执行目标对象的方法的前、后追加功能;- e0 k0 G. ^' T, |0 g
必须有参数;第一个参数的类型必须为ProceedingJoinPoint;% Y- M2 h+ G+ `2 s
通过ProceedingJoinPoint的实例的proceed来调用所监控的
8 d8 ^+ F! ~7 w Y m 目标对象的方法/ a& u$ B* A. g/ S" S% {% d: O+ y" S
1 定义一个pointcut,通过方法名来作为pointcut的名称来引用
* m% z% Y5 H. L% x0 O! [0 f0 n8 ]% g Y! Y (1).@Around(“com.javakc.spring.schemaaop.TestPointcut.t1()”)
! V! K: }( |' z/ G1 W/ S4 ] (2).@Around(“com.javakc.spring.schemaaop.TestPointcut.t2()0 A3 B+ B0 D8 f3 j' I5 ]: F
&& args(str)”), A2 D' y7 V0 Y# w/ P) _2 C
2.直接引用匿名的pointcut
4 W$ q: G1 @, H8 z$ _ (1).@Around(“execution(9 F. Y" g! N1 m# k1 g3 `2 p
* com.javakc.spring.schemaaop.Api.test1())”)1 u" J; y/ F0 t
(2).@Around(“execution(
6 ]0 n1 `5 c2 d0 W" V' ^ * com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)
8 v4 u3 t5 K, j- c0 g // @Around(“com.javakc.spring.schemaaop.TestPointcut.t2() && args(str)”)8 b5 j9 C0 M8 u& |; u& i
@Around(“execution(* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)) K. J% J; H6 i8 E$ I
public void testAround(ProceedingJoinPoint prj,String str) throws Throwable{1 c! B, |+ q/ ?3 T
System.out.println(“around1==========before1pointcut==>”+str)1 L( }8 d/ y; l5 a
Object obj = prj.proceed();
0 h8 h5 {& j2 w; U$ B System.out.println(“around1==========after1pointcut==>”+str);1 K4 R8 O3 g% a' e6 t( d, l$ T- y( L
}. s7 {8 j, k% V" J& |" A7 h
5.4.3.@Before
+ R+ t1 r9 c7 X2 K+ S( J 注解@Before在执行目标对象的方法前追加相应的功能4 C3 p2 p# L9 b2 N" w6 X( i- r
1 定义一个pointcut,通过方法名来作为pointcut的名称来引用
% @* e5 i, E% f z4 G6 j (1).@Before(“com.javakc.spring.schemaaop.TestPointcut.t1()”)
5 D/ w7 T- }$ f (2).@Before(“com.javakc.spring.schemaaop.TestPointcut.t2() && args(str)”)1 t, P6 R* J$ E) i$ Y% ^
注意args后的名称与参数名相同9 J3 k4 t3 f/ l L/ ^
2.直接引用匿名的pointcut6 T$ P2 N) x; z0 d. s9 S
(1).@Before(“execution(* com.javakc.spring.schemaaop.Api.test1())”)
# r2 I) X9 x, j( ^: k6 ^ (2).@Before(“execution(* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”); D0 Y9 n8 K1 s6 u: O
注意args后的名称与参数名相同% Q% T4 f8 g. Z$ i+ t6 D8 c' _( p
// @Before(“com.javakc.spring.schemaaop.TestPointcut.t2() && args(str)”)
3 a+ l J1 w: B8 W- |6 c; I5 n @Before(“execution(* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)& G5 ]7 ]5 p, z0 g
public void testBeforeParam(String str){! g c' f% L, ?
System.out.println(“before1=param=>”+str);
- {) [8 |* j- r8 U3 s4 H% b }0 m8 X' n5 }: k! n; i
$ u Q( X* }. n
5.4.4.@After
8 o8 u, {- ]% \3 H 注解@After在执行目标对象的方法后追加相应的功能
5 e8 M' O1 B; B0 j- j 1 定义一个pointcut,通过方法名来作为pointcut的名称来引用
4 v7 t7 p8 V O# [ (1).@After(“com.javakc.spring.schemaaop.TestPointcut.t1()”), K. j" W2 n! O) `, J5 @. m& s
2.直接引用匿名的pointcut
3 d$ u) ?$ s p. ?" n( _ (1).@After(“execution(* com.javakc.spring.schemaaop.Api.test1())”) c3 J7 d% ~3 S1 n2 h3 z! n( u
@After(“com.javakc.spring.schemaaop.TestPointcut.t1()”)9 n- A; Z' ~! [
public void testAfter(){1 \7 _) t4 W2 f- C6 P
System.out.println(“after1== >pointcut”);
; v7 R7 A3 H4 W% |; v }) _6 e: ^ F/ y5 d; l8 M% ?; Q0 x
5.4.5.@AfterThorwing
% |* ^4 p" Y4 n1 w7 j
5 Y1 a+ u% F* U+ l; P* Q& s4 ^1 T# O. D
- 描述一下spring中BeanFactory和ApplicationContext的差别" l' n6 j5 ]. W/ d- U6 Y1 h6 D1 F8 L6 [
( P+ b& F6 x6 w' G; W! G
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”); 6 @9 l$ {7 [+ o& _# z
- 谈谈spring对DAO的支持! I1 s& ~' K/ L0 T5 `/ i. x
. Z( h5 F2 v4 u. A9 B
Spring提供的DAO(数据访问对象)支持主要的目的是便于以标准的方式使用不同的数据访问技术。
: Z3 Q) i& n0 u$ ? 简化 DAO 组件的开发。
5 F/ O S( [7 n5 c; h' NSpring提供了一套抽象DAO类供你扩展。这些抽象类提供了一些方法,用来简化代码开发。5 k4 M# H6 p; L% {$ Q; \
IoC 容器的使用,提供了 DAO 组件与业务逻辑组件之间的解耦。所有的 DAO 组件,都由容器负责注入到业务逻辑组件中,其业务组件无须关心 DAO 组件的实现。
) N: y6 t# q9 F" m! z. c 面向接口编程及 DAO 模式的使用,提高了系统组件之间的解耦,降低了系统重构的成本。
6 [& u4 N. m- m 方便的事务管理: Spring的声明式事务管理力度是方法级。: K: [' J: c" G7 b0 ?) Z3 q3 m
异常包装:Spring能够包装Hibernate异常,把它们从CheckedException变为RuntimeException; 开发者可选择在恰当的层处理数据中不可恢复的异常,从而避免烦琐的 catch/throw 及异常声明。9 C9 i& p7 G) B/ {' F# ^) j- l, Q0 F
1 P6 i# ?* h% n& f& H. ]
5 a% ^9 {( j: H% G$ f- 谈谈spring对hibernate的支持
+ [7 J. u3 L, c5 c, B
& k9 V5 l2 t; V, A! I
在所有的 ORM 框架中, Sping 对 Hibernate 的支持最好。如 SessionFactory 的注入、HibernateTemplate 的简化操作及 DAO 支持等。另外, Spring 还提供了统一的异常体系及声明式事务管理等。
1 N4 ~+ f w$ s7 Z* b* t 一旦 Hibernate 处于 Spring 的管理下, Hibernate 所需要的基础资源,都由 Spring 提供注入。Hibernate 创建 SessionFactory 必需的 DataSource ,执行持久化必需的 Session 及持久层访问必需的事务控制等,这些原本必须通过代码控制的逻辑,都将由Spring 接管ataSource, SessionFactory, TransactionManager等,都将作为 Spring 容器中的 bean。将这些bean 放在配置文件中管理。4 P) V7 f! ~: q' [) q
1、通用的资源管理: Spring 的 ApplicationContext 能管理 SessionFactory,使得配置值很容易被管理和修改,无须使用Hibernate 的配置文件。详细配置如下:( b$ K8 X, x8 c" V% ^' w
. L! c. b7 F- H$ z: o$ D: e: v
class=“org.apache.commons.dbcp.BasicDataSource”>
. Z/ v. x# Z! E' b/ i8 l* W+ h' ?0 R * c, p3 F8 h7 G$ O' M
oracle.jdbc.driver.OracleDriver
3 O) B4 G8 f9 q+ Y1 ]5 o& ]
, [: O+ @& }6 H- [+ B1 `. D C
& L4 a: I# v( h1 \% ^% f( j1 C jdbcracle:thinlocalhost:1521rcl" [: ?- u* o/ L/ r& x
+ m% {1 y* C0 K% m" ?! s 7 A8 S0 w$ {4 V$ j+ Z) m: u
javakc2
+ o1 K" F! `3 y
4 I- p5 P& W5 [ $ y: a. U% C9 _$ U/ D
javakc2
% ?( L% w/ J" C! p& ?( B
5 O7 t5 u- d+ t & y- b2 D2 T# K0 ^
! m' g" v9 y; ?/ v+ c class=“org.springframework.orm.hibernate3.LocalSessionFactoryBean”>
6 {9 ^" [4 R# }0 W% J
7 P; q2 C* U5 @: w ^1 z) E
8 [$ P, u1 f# Y
4 d) J0 p) ] t% a& B) l, r com/javakc/spring/h3/UserModel.hbm.xml! E9 F* ?: y" o6 y
5 Y5 `( J* K5 H * j( S) O: Z; [ X7 R# t
* l/ l$ @+ ?9 C
1 H: Y+ V, C4 q% W hibernate.dialect=org.hibernate.dialect.OracleDialect
6 m" |* g! Y( N
1 \9 B8 D9 K1 U5 A! {- d
4 o5 k" `! v$ r. r& A 2 [" @$ K/ [8 _) N4 E
; c& M8 [4 O4 Y3 l& {$ a
, ?: x1 q$ T. q, e# f$ V7 S 8 o: L( W E/ O7 k
如果需要使用容器管理的数据源,则无须提供数据驱动等信息,只需要提供数据源的JNDI 即可。对上文的SessionFactory只需将dataSource的配置替换成 JNDI 数据源,并将原有的 myDataSource Bean 替换成如下所示: class=“org.springframework.jndi.JndiObjectFactoryBean”>
9 B. y2 I* f0 l- l: k
9 R# x, ~+ R' j! F4 k, e java:comp/env/jdbc/myds# r( w+ s o0 d+ Y, T
: j+ ?& L: s8 ~0 S( @
2、有效的 Session 管理: Dao类继承HibernateDaoSurport后,Spring 提供了 HibernateTemplate,用于持久层访问,该模板类无须显示打开 Session及关闭 Session。它只要获得 SessionFactory 的引用,将可以智能打开 Session,并在持久化访问结束后关闭 Session ,程序开发只需完成持久层逻辑,通用的操作则由HibernateTemplate 完成。 3、统一的事务管理。无论是编程式事务,还是声明式事务, Spring 都提供一致的编程模型,无须烦琐的开始事务、显式提交及回滚。 建议使用声明式事务管理,Spring 的声明式事务以 Spring 的 AOP 为基础。可将事务管理逻辑与代码分离。代码中无须实现任何事务逻辑,程序开发者可以更专注于业务逻辑的实现。声明式事务不与任何事务策略藕合,采用声明式事务可以方便地在全局事务和局部事务之间切换。 Spring声明性事务有两种配置方法,一种是xml配置:
. y7 w* v6 Y4 V( Q- H/ ?4 P
b% h* _& ~. `
/ n$ n9 S5 I1 O2 i/ r0 C
/ k) ~ B! \* {+ v1 Q' R$ L- B, [
" M9 `& p0 H- x; \$ X% g 7 |+ z. P. l+ U% H
6 Y- y$ Z$ c0 X% I
9 s# V, v% D1 l/ ^7 _- H3 B R H- \+ f( p# |+ a( n5 ^
6 L- K( f$ Y# H$ ?- l8 `: N3 H, x
* ^( K( X% N/ P4 }$ q$ ~ 6 r S; }3 H8 @+ y+ F
, k. c' G6 [" G# ~ * L8 p I. |4 ]8 l
另一种是通过注解,在需要添加事务的类上注明 @Transactional
, w6 Y* U5 k7 ~ K8 \* U9 n+ rSpring2.0之前事务的写法6 Y+ c# i& d% b& u. i
- R- }. W0 L1 \# t
: s# d. z' r C- ?* ]6 p: E class=”org.springframework.transaction.interceptor.TransactionProxyFactoryBean”
$ m5 _0 S( P1 G9 T) N* H3 a/ U0 ^; \9 Z7 y9 K; n, e7 s2 r }
abstract=”true”>- I0 `7 y, v" k
0 h0 z0 E1 m3 N" b* c
0 ]1 q4 B7 O6 G5 L; }
" @6 }- H i7 ~! j# }6 B: Q2 Q+ u* ]
PROPAGATION_REQUIRED,readOnly1 w4 f' o6 m1 a' ?1 L
8 U/ }/ v# \8 n6 {$ @
PROPAGATION_REQUIRED
7 d. ?$ I; i. A$ J% M; P/ t. n1 u" X1 c; z- D
6 H: n* A/ E) u% A; V
; H. W6 m7 G0 v
9 R7 Z5 N U1 J2 X8 K8 \3 j | # K+ f* b3 t* x; p7 y" l
1 B% i- Y6 ]) R9 M: p- `
- 谈谈Spring对事务的支持
2 N+ y5 W6 o1 A) A2 |3 F/ R& W6 c5 s R% N) ?' y0 s& P) J
L3 A+ k+ o# y0 Q* n1、声明式事务管理:
1.流程:由客户端访问—-aop监控—-调用advice来追加事务 2.做法: 2.1 在配置文件的头中引入xmlns:tx 和schema的文件 2.2 2.3 注入数据源 8 e, @. j. V& V2 _( V, V+ }
3 T8 g: L4 x& K: n6 d; P5 s& F, K
, U. e+ F& W, E; s; k( r* V0 [* e* Y
+ X, ?8 P: \. c! V2 h
# e4 C& s/ c% j! N% _; X6 i& _. j0 a4 f7 t3 N& }
2.4 由spring实现的事务管理,但需要注入数据源
0 x L( ]6 R$ D2 Y" B1 D" U* }& I* m0 R" Z2 `4 W7 C
, `! B" j4 x! \" W8 i2 j! G! U! O0 k2.5 事务监控所有的方法(事务加强)
% _1 U$ V1 A+ @3 {4 D$ w1 [$ a
5 L" g. g) i: c: W" |! n' _6 K- B! G6 w- s
( t- A+ Z% ~/ U% r; t8 O
9 ?4 M/ e7 ^ a" H: J8 d2.6 定义切入点 , w# y& f0 ?. w
4 s& n: `; q! `: `
8 P2 p8 o: j. W4 z# G) ?6 [* [4 t* u, m% m& {2 J; p$ @
& a" e# w7 W+ B% M
2、使用注解实现事务管理: 1.注解@Transcational (可以在类上,也可以在方法上) 2.在配置文件中同样需要注入dataSource和spring的事务管理 3.使用注解的方法来追加事务 注解驱动
1 G6 Y; b& t6 \; P# H ~- {& H* o- x" @
4 p$ t0 J0 S! u* H如何在Spring中使用Hibernate的事务:: ?+ @1 Z* H1 j! a
' p. {2 \' e! p8 o; y, x$ {7 R* n& t
4 n! e& D$ D: h; z* E N1 V% @; Z2 Q1 g
如何在Spring中使用JTA的事务:* @- {# p- n' ~ j: z0 c
7 |. \5 J; y& u/ E4 ~9 r
|