Spring
+ U$ ?8 Z7 z- r w8 ^5 T, J- 是什么?
% k" e9 M% V& {( b" E1 W
" Y2 q+ M* t/ M& `/ P5 h2 f
Spring是基于JEE的轻量级的应用框架
3 @0 m4 Z6 P- k {- 有什么?8 r! T2 X% n8 j
. {* g1 T. Z& f- t$ \" Y) u2 h
" I5 k3 J8 v9 W3 K# L w
每个包的功能: Spring MVC:spring 本身提供的web 框架 WEB:集成其他的web 应用的框架,或者说是对其他web应用框架的支持。如struts,webwork JEE :集成一系列的jee的技术(对JEE技术的支持) DAO:封装了JDBC;(对JDBC的支持) ORM:提供了对ORM工具的集成(支持) AOP :面向切面编成 CORE:spring的核心包,提供bean的工厂和IOC容器
+ H' z+ x& ^* l7 q7 u% U) n; `9 ~& G- 能干什么?3 y7 V6 D' ^0 P% J& T8 |
! b A' B% P" b( m/ n
把一系列的jee的技术有效的组合在一起形成以良好的系统
$ R% d2 B6 E' k- 怎么用?5 b! N$ v6 r6 I) }- {7 `
, y+ ?1 s) s7 [- 搭建web工程,引入spring的jar包
) S. q# R) R8 f9 H - 在web.xml中添加如下配置1 |- h9 c" o# [! y3 a' y# w
2 M! V! v! _0 V$ [
/ K& O& U) M; ]1 Z% T" \0 w( ? B9 U5 w! t" z2 Z, x9 U7 {$ T9 ?
contextConfigLocation
& a3 M5 h3 G" }+ K2 m# L9 M/ G classpath*:applicationContext*.xml
" c4 O* }) J3 r! t 0 ~& Y Z1 _4 s, E
0 ^5 X: t k$ t; }$ U; U# l struts2
: f( s4 w+ v$ Z! [
5 _/ c8 I2 d ]: }+ j8 I. M, z org.apache.struts2.dispatcher.FilterDispatcher
0 i7 q# ~% a2 n / t/ @; B" n3 ~
{ o; k2 A! d4 q
9 [; I1 M- j7 P1 F% r* b1 K
struts23 E( O, e: {! G. L5 c5 G. C
/*5 v/ Z6 R" l D: U2 q3 n' S
8 C8 l) n9 i. v2 l% u# X/ e
) ^, l! C& S7 Q+ S5 d+ v
" j+ a: Z$ j: w# f. q2 \ org.springframework.web.context.ContextLoaderListener
. [% ~5 T6 D/ x# P+ T* ~! S" A
w* a2 X- H& q3 E8 o; o" I - 部署
6 D' r3 B. S) p/ c' U7 N+ E
8 P1 m+ ?$ R! H& R. i1 h! |1 F; r
, ?6 }, g4 b) E& v7 s6 }1 g }1 Z- S2 z# |
" i! v: F* W5 n, N8 Q- M
- 容器和bean
* p3 l' o+ N/ I+ K
Bean :是指受spring的ioc管理的对象称为bean 容器 :(与jee的容器类比) Jee :提供组件的运行环境和管理组件的生命周期(不能单独存在) Spring :提供bean的运行环境和管理bean的生命周期(可以单独存在)
8 D7 |1 G5 _( S' v, I1 S; v
3 ~, L# \% A! D2 C( g6 R( [- DI依赖注入
1 A$ o7 O b8 v- ], P
1. 应用程序依赖spring注入所需要的对象 IOC和DI是对同一种事情的不同描述 2.setter注入: 在配置文件中将接口的实现配置为bean在应用程序中注入bean 例如: 在配置文件中
6 d* d3 L4 ~+ {5 @
/ }! d& ?- t, K% I. l! j* Y) i( a1 g1 T/ O/ y& Q
在应用程序中 Public DBDAO dao ; Public void setDao(DBDAO dao){ This.dao = dao; } 3.构造器注入
, Q: a/ c8 B; Q% U' `/ }5 [0 [4.ref 表示参照其它的bean 在参照的过程中一定要注意死循环 5.自动装配———–〉no 自动装配根据名字来匹配相应的bean 尽量不要去自动装配 6.lookup注入 7.singleton 1.单例模式是整个的jvm中只有一个实例 2.spring的singleton是指在spring的容器中只有一个实例 一个生命周期中只有一个实例 8.DI的优点: 1.程序被动等待,强化面向接口编成 2.切断了对象或组件之间的联系,使程序的结构更加松散,运行和维护更加简单
$ ]4 y7 d; }! Y* T; D- e- Aop面向切面编程% u* J9 `9 m* m& B
9 V$ z; S3 [& g" C2 A
1.AOP面向切面编程 一些较好的模式或者是示例—-范式 M+ j6 _% O E; f* _
切面:一个切面代表我们所关注的一系列的共同的功能点(模块之间的共同的功能点) 2.AOP的思想: 主动—->被动(追加功能)0 r( x8 z: h3 f! z
3.AOP 的概念" c: U& C4 P2 j- C1 V
1.切面 :我们所关注的功能点 2.连接点 :事件的触发点(方法的执行) 3.通知 :连接点触发时执行的动作(方法) 4.切入点 :一系列的连接点的集合 (连接点的模块化) 5.引入 :扩展的功能 6.目标对象 :包含连接点的对象 7.aop代理 :实现机制 8.织入 :把advice和目标对象连接起来 4.AOP的事件机制2 G: ]( g `, T! ^, u
1.通过切面找出一系列共同的功能点 2.找到目标对象(在标准的spring 中 接口的实现类为target) 3.找到切入点 4.确定连接点 5.通知spring AOP,查询xml文件,通过代理找到advice。 6.由aop代理来实现动态织入 ) E4 S, Z" l+ f% j7 F
8 F! c7 o7 H% P! j" W
k' Z5 A7 Y2 C @6 f+ U
- {/ F0 `3 d5 n7 G9 k x4 A* @3 z" Z; c/ p& a& p
# }/ w, E2 Y" _( r5 ^. N; F0 l# V: W4 M9 i# a- \
5. AspectJ4 _9 `3 @0 `+ T; ], b
5.1.在xml中配置比较烦琐
8 T. [" G+ M+ A& D 所有的入口必须从一个代理(ProxyFactoryBean)开始4 g& Q' [! i1 P6 [$ Y0 q
6 t1 _2 _0 x0 |+ H& n
5 I2 P. m9 K) ^. B
2 M& i0 s! U0 Q5 R% a+ V6 ~+ V
5 Y* E$ m2 _2 T# H2 w3 l
! e7 }$ N- o5 p+ U
$ [5 s, k! f0 }& } & |8 @1 P3 F0 a
/ D& V5 j/ x, r' M
expression=“execution(* com.javakc.aop.MyTarget.t*())”/>
1 h" H: r# ~& X: _0 {) q- }
9 J8 O* O% H4 h! z) Z
5 l$ R4 n8 ]/ H2 m4 Z $ L% [1 W2 g2 G$ h5 Z2 O
}( w' f& U. e& x+ x L. \
; h" ^; _* Y% F' n6 g# r5.3.使用注解的方法相对简单# P7 }+ K* `& I! C3 y% T
@AspectJ的基本语法" q' L) f7 g/ n; Z
1.@Aspect声明一个切面,将一系列的共同的功能定义成一个切面& h! Z0 L1 O/ t. `) P, D$ L3 G' c
直接在类上定义@Aspect
% [" F, J) N. @5 D) p 2.@Pointcut声明切入点
+ K, [' D5 H- j* ]# m' [! J) K& G 2.1、用一个专门的类来定义pointcut,类中的方法名就是该pointcut的名字
" g$ Q1 ]' L4 N w* k; \" V 2.2、可以使用匿名的pointcut
+ `1 g$ f( x3 n; r5 J. { 2.3、执行切点的几种方法7 A. a( Q* F$ W; y, y/ s; ^6 M- @) h
2.3.1 execute(public * 包结构.*.*.(..)) 可以指定到具体的方法3 I" f" M6 m4 S
2.3.2 within 指定到包,不能指定到类
* c+ z. ]* o) K$ D within(”com.javakc.spring..*”)
; D' m1 \9 X9 R 2.3.3 this 指定到实现接口的所有的实现类
" T7 \9 w e- P8 B# R 2.3.4 target 指定具体的实现类. H& W, k- ^9 R, K
5.4.advice的五种类型的示例( q* F2 z( R3 I* r
客户端必须从接口走才能得到监控,实现想要追加的功能# j+ {* Y: M+ X" D: D+ a
5.4.1.@AfterReturning(pointcut=”” returning=”retVal”)
7 ^6 U( V( t' c+ p- Z 追加的方法的参数名字一定要与retrning的名字相同3 V; q& d }7 z
在注解@AfterReturning中必须加上pointcut和returning两个参数1 L5 L0 @6 P5 K* T2 `! C. V! \) {$ k& l
pointcut指所要监控的目标对象的方法3 i0 c: I6 U+ l4 O7 { f
得到目标对象的方法的返回值,来作为参数,进行下一步的处理,参数没有顺序,按参数的名字进行匹配% `+ y/ F7 f1 e4 t
完成追加的功能- q1 Y R# n& P: t
1 定义一个pointcut,通过方法名来作为pointcut的名称来引用$ w# L' T& W% T! k; s
(1).@AfterReturning(“com.javakc.spring.schemaaop.TestPointcut.t4()”)
0 F( M5 f! u7 O2 }: K+ u: E% } (2).0 U) O0 a: ^% F4 `
2.直接引用匿名的pointcut
- r; p6 t, P6 l! m (1).@AfterReturning(“execution(0 D9 f6 r3 q0 k M
* com.javakc.spring.schemaaop.Api.test4())”)0 E% S) Z% j- I2 i8 O/ W; Z
(2).@AfterReturning(pointcut=
2 v4 s' Z7 i9 P' c- r% g “com.javakc.spring.schemaaop.TestPointcut.t4() &&
+ u+ W: h" p j |( t args(str)”, returning=”retVal”)9 S8 |3 `9 O" j5 F9 a: f2 Z9 s
@AfterReturning (pointcut=”com.javakc.spring.schemaaop.TestPointcut.t4() && args(str)”,returning=”retVal”)
' [( S% d7 s, j: E public void testAfterReturning(String str,Object retVal){
& x, P% k) L5 e' K3 r6 u! E8 z System.out.println(“afterReturning1=>”+retVal+”=>”+str);- `" _0 L" o- F/ E
} T4 k9 W/ J# r1 S( S4 ^1 A
5.4.2.@Aronud7 v/ m6 @" `" L5 }* G. m
注解@Around环绕追加功能;
9 P2 I: a; `6 N 在执行目标对象的方法的前、后追加功能;* O/ s* j+ e S k+ p
必须有参数;第一个参数的类型必须为ProceedingJoinPoint;
8 E3 k; z( J6 `) m& D; k. K/ l 通过ProceedingJoinPoint的实例的proceed来调用所监控的
2 t- @. f4 P& J3 U 目标对象的方法3 L3 {4 W+ L- D. J5 _! y6 B
1 定义一个pointcut,通过方法名来作为pointcut的名称来引用
) n+ }* w( l+ z! @ (1).@Around(“com.javakc.spring.schemaaop.TestPointcut.t1()”)
6 T9 h5 I+ F3 C+ P I7 ]2 ? (2).@Around(“com.javakc.spring.schemaaop.TestPointcut.t2()$ W1 @; D' c- p
&& args(str)”)
' b4 ]2 d4 y8 B# v4 X8 }* h& X 2.直接引用匿名的pointcut7 p# L' p% c: j4 i; \
(1).@Around(“execution(
, o2 y0 ~+ l' D6 Q2 T+ A * com.javakc.spring.schemaaop.Api.test1())”)
/ b) u F0 \2 E4 n3 H, b" ~ (2).@Around(“execution(- u, q. D8 ~/ y( H: i' R/ P6 J1 g7 V
* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)1 r, M) Z8 O8 L+ n% C- \: Z
// @Around(“com.javakc.spring.schemaaop.TestPointcut.t2() && args(str)”)
6 C/ l2 X$ {+ O+ J, _9 j- B @Around(“execution(* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)1 Z% F# p' w+ K9 \
public void testAround(ProceedingJoinPoint prj,String str) throws Throwable{
' j( ~5 U" P& R4 ~ System.out.println(“around1==========before1pointcut==>”+str)
7 L2 _$ P5 L8 i- a2 Q Object obj = prj.proceed();! ]* y t2 y6 K2 j7 W! m
System.out.println(“around1==========after1pointcut==>”+str);) d- b# c( S8 x
}4 [2 L7 D& g" L
5.4.3.@Before8 k% V, Z1 X* T. J8 z4 w
注解@Before在执行目标对象的方法前追加相应的功能
: S# m5 A' s- S 1 定义一个pointcut,通过方法名来作为pointcut的名称来引用
3 x J0 [4 ?$ x$ M/ n7 Z (1).@Before(“com.javakc.spring.schemaaop.TestPointcut.t1()”)
* n; S# |- `8 u$ w) ]' v (2).@Before(“com.javakc.spring.schemaaop.TestPointcut.t2() && args(str)”)$ |0 ~% ?) f" E' X
注意args后的名称与参数名相同1 j. e( J8 X) m- J
2.直接引用匿名的pointcut
* ~2 m3 O& o+ |8 {; R+ X) X5 ]& K/ n/ r (1).@Before(“execution(* com.javakc.spring.schemaaop.Api.test1())”): L& o, H U6 H" w/ W0 H
(2).@Before(“execution(* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)- N' O, q/ _2 W p
注意args后的名称与参数名相同( W5 a) R! j! Y; n$ f6 [6 |; s7 C" O
// @Before(“com.javakc.spring.schemaaop.TestPointcut.t2() && args(str)”)/ Q3 B" [4 x+ O! d
@Before(“execution(* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”) Z$ n& b; ]* ?% W! t
public void testBeforeParam(String str){
1 E: {, A+ I g9 W: j System.out.println(“before1=param=>”+str);
: @2 V- n7 E$ j/ g+ ~# U* J3 e }
# g/ H! C1 ^: k# |9 P/ s n5 B [2 q/ C+ C8 F4 a( B
5.4.4.@After
! O: ~! V" a1 @5 k" n* T( W 注解@After在执行目标对象的方法后追加相应的功能
0 o' B6 G: \& l1 c/ J 1 定义一个pointcut,通过方法名来作为pointcut的名称来引用' A( _' l2 P% n4 l" u
(1).@After(“com.javakc.spring.schemaaop.TestPointcut.t1()”)9 u& F% u/ |5 R+ g' ^: d
2.直接引用匿名的pointcut9 P3 R- S# @, z/ f3 t( |. f& a
(1).@After(“execution(* com.javakc.spring.schemaaop.Api.test1())”)
, @: H! E! f, w! |) d8 y( ]5 A @After(“com.javakc.spring.schemaaop.TestPointcut.t1()”)! Z1 K3 d) y1 d- B% F& l4 ]5 n
public void testAfter(){
2 O/ v; J% M/ H' Z5 t System.out.println(“after1== >pointcut”);9 ^! ~/ m* @! n: b# }$ D
}- R/ [4 t0 U# g* y( V# v. e
5.4.5.@AfterThorwing
+ o H4 }+ O) U. N v# s8 G
2 ]: I2 P5 y& ~- A$ P+ B! ~* V7 {; U
- 描述一下spring中BeanFactory和ApplicationContext的差别3 i( U m& ]6 @+ i8 K% ^0 N* X
' g7 x/ b' \3 \( L% p& x
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”);
* L' {/ Y9 i1 B3 ~" O- 谈谈spring对DAO的支持4 g: j2 q1 A9 t; d$ v, Z1 h0 o6 V
6 w! D7 g8 J2 H. T7 _" j' X5 `
Spring提供的DAO(数据访问对象)支持主要的目的是便于以标准的方式使用不同的数据访问技术。$ \1 b7 Q) |' J) p- O* T
简化 DAO 组件的开发。$ n/ _( c" |1 T: D b9 J- B
Spring提供了一套抽象DAO类供你扩展。这些抽象类提供了一些方法,用来简化代码开发。1 ~2 o, S- e6 {6 Z3 ^
IoC 容器的使用,提供了 DAO 组件与业务逻辑组件之间的解耦。所有的 DAO 组件,都由容器负责注入到业务逻辑组件中,其业务组件无须关心 DAO 组件的实现。" P* q. K/ ?" c- ^0 e1 H) M8 z
面向接口编程及 DAO 模式的使用,提高了系统组件之间的解耦,降低了系统重构的成本。/ o7 u( ~8 M/ b- V- K) X* o
方便的事务管理: Spring的声明式事务管理力度是方法级。
: |1 }- A' S+ W( }0 ] 异常包装:Spring能够包装Hibernate异常,把它们从CheckedException变为RuntimeException; 开发者可选择在恰当的层处理数据中不可恢复的异常,从而避免烦琐的 catch/throw 及异常声明。3 `! ^, Q- C4 q; F1 l# r
. u+ @; c4 o: W; G& | h
9 b2 T9 \ u% w3 }; v! b- 谈谈spring对hibernate的支持
5 B- |3 @' Y* {- t) z* g& [' u6 O% P" J8 t" ]3 t; c* x; h2 M0 e
在所有的 ORM 框架中, Sping 对 Hibernate 的支持最好。如 SessionFactory 的注入、HibernateTemplate 的简化操作及 DAO 支持等。另外, Spring 还提供了统一的异常体系及声明式事务管理等。, q2 }! ?$ t/ d
一旦 Hibernate 处于 Spring 的管理下, Hibernate 所需要的基础资源,都由 Spring 提供注入。Hibernate 创建 SessionFactory 必需的 DataSource ,执行持久化必需的 Session 及持久层访问必需的事务控制等,这些原本必须通过代码控制的逻辑,都将由Spring 接管 ataSource, SessionFactory, TransactionManager等,都将作为 Spring 容器中的 bean。将这些bean 放在配置文件中管理。
1 _5 ^% V% T7 U8 U8 |3 F" x4 I 1、通用的资源管理: Spring 的 ApplicationContext 能管理 SessionFactory,使得配置值很容易被管理和修改,无须使用Hibernate 的配置文件。详细配置如下:
1 ~* |. O6 B' c6 u! r
8 d- O! ~ T! ?. X( r class=“org.apache.commons.dbcp.BasicDataSource”>+ E" z) R- T/ ?; i2 ~, L1 m0 i
/ z* A5 z6 M1 _5 R/ H F oracle.jdbc.driver.OracleDriver
3 t5 n+ @0 o" K K, e$ M4 I9 @ . U2 M' O4 r$ R+ S
. I( n8 g. F" \8 o7 b jdbc racle:thin localhost:1521 rcl5 t, S3 d; |: ]6 s p$ v% t
$ K; w! p9 C, }) i# I1 _, d9 ?, a4 d
' l. ?# l A! k
javakc2) \5 m7 l8 w; a" _: G
/ t( z; I" o. v# Z
0 m7 _8 }/ Z% s. u+ @5 o+ z javakc28 }( ^+ y; d" [) M8 v# j7 G) b
1 @; Y8 k: P9 W& ?" Z+ o
# q! Q5 P7 G3 v2 Y, }& O
% F5 f$ D/ }3 y% ^% f4 K! w
class=“org.springframework.orm.hibernate3.LocalSessionFactoryBean”>
) G1 q. O! l k/ D# k; t6 P# \ ' x: M; |; \* G' ?6 Q/ \- V
1 S" V y9 F, U
. w( n: ] D0 K+ u& h0 M com/javakc/spring/h3/UserModel.hbm.xml
" n' s7 D* l* g9 a* Y Y4 T" v - t8 Y X4 S* n+ z6 `, g# D
2 q6 j0 f2 l4 f; j9 M* y9 k- s 8 r9 B- K5 F2 {
# u3 @* k# R7 G0 \5 j, f5 D" I; O
hibernate.dialect=org.hibernate.dialect.OracleDialect
% a) j% a% L( r. o( B, ~( e& z
& f* A9 D" q5 v" {0 a: ^* i , d$ {; ]; [0 G* h: H) W0 d
: x4 R9 ?" O3 U J% o8 ^
# I9 E* u$ M0 L. p
% h) F$ ~' s' T" D
& v; n( L# L3 F; V0 H6 ?2 G 如果需要使用容器管理的数据源,则无须提供数据驱动等信息,只需要提供数据源的JNDI 即可。对上文的SessionFactory只需将dataSource的配置替换成 JNDI 数据源,并将原有的 myDataSource Bean 替换成如下所示: class=“org.springframework.jndi.JndiObjectFactoryBean”>. ?8 j- G# e6 y; f7 E! [( r! @
; z' B5 Y: T9 o+ r- y; c* c) K java:comp/env/jdbc/myds9 u0 b" N1 b6 r, I# O8 |
+ f3 g x) w" E4 o7 N/ Q
2、有效的 Session 管理: Dao类继承HibernateDaoSurport后,Spring 提供了 HibernateTemplate,用于持久层访问,该模板类无须显示打开 Session及关闭 Session。它只要获得 SessionFactory 的引用,将可以智能打开 Session,并在持久化访问结束后关闭 Session ,程序开发只需完成持久层逻辑,通用的操作则由HibernateTemplate 完成。 3、统一的事务管理。无论是编程式事务,还是声明式事务, Spring 都提供一致的编程模型,无须烦琐的开始事务、显式提交及回滚。 建议使用声明式事务管理,Spring 的声明式事务以 Spring 的 AOP 为基础。可将事务管理逻辑与代码分离。代码中无须实现任何事务逻辑,程序开发者可以更专注于业务逻辑的实现。声明式事务不与任何事务策略藕合,采用声明式事务可以方便地在全局事务和局部事务之间切换。 Spring声明性事务有两种配置方法,一种是xml配置: / P) X! ]$ ~- z6 x
0 n, K# o4 `+ q( D9 }9 b
2 [. s5 ?* _5 ?2 q4 e
* h6 T% p9 g* `/ @6 i' P
+ q; l0 w. N% N& X& ~/ b* Z 9 [) Z$ I9 n& _; n" L+ }) m
7 l9 P* K1 g+ ~. m/ J! C
& \1 q7 h' K# W6 `1 w m/ s 4 L: p) ~+ F% s* p, _ q+ k3 N" M! x
1 G5 |* F6 l& s( b' w% t
- \$ m2 [: W% T" U# V
% n2 q- V6 U/ E' W * L' P+ Z3 i" O
4 a* |! ]3 g6 I$ Y7 ?' a" {) |
另一种是通过注解,在需要添加事务的类上注明 @Transactional , h( t$ b' X; p; ^8 Y9 m6 p
Spring2.0之前事务的写法
$ I5 f. l' W# J- g5 k* L3 c: d$ V! @8 w" q
% u5 k( C: W0 T& z class=”org.springframework.transaction.interceptor.TransactionProxyFactoryBean”6 A# K$ E9 _1 A) y5 e3 o6 e" m
+ M5 n, f5 U8 A0 N4 h, J
abstract=”true”>+ f0 g8 K8 V0 r2 k7 F7 x8 z; M0 `
5 v3 Z. q ^ d1 P& ~# H1 \: u* r! c- o
" \( K1 G3 A1 g$ ?8 r' [1 V2 I( x- L3 S. h' {
PROPAGATION_REQUIRED,readOnly/ \+ r6 l7 `- x C
8 ^1 C% c% w$ s PROPAGATION_REQUIRED
' A# C9 |7 C- I, T: N! m! M0 @9 z. `% `) r. p9 P' n0 @0 D
/ H* N6 M- t* @8 @3 m$ q* b+ J3 b8 G
8 w4 k |* O6 W/ c: W0 r- h' e
9 O; @, p1 N. z; e9 U' \
|
! B) [6 Z5 |# x' x& K. ^1 ]; {; H/ C( A9 \2 W% N! l9 i
- 谈谈Spring对事务的支持1 y' ~! [5 C7 ~, \1 D& e
7 m5 v8 N1 ~( c9 V
+ F) ~" W2 V4 H' C2 ^% g# L, y1、声明式事务管理:
1.流程:由客户端访问—-aop监控—-调用advice来追加事务 2.做法: 2.1 在配置文件的头中引入xmlns:tx 和schema的文件 2.2 2.3 注入数据源
' }- ~8 u( {* o
9 x, e' t- c3 J/ Y) E& u4 u; D _3 i8 [
) n% ~/ [) q. y) G% \/ z/ a. ?, Y. {% i! o9 T0 ^. M9 O( a, f
" }8 v" U, R& @9 e9 y. s7 \/ G# D2.4 由spring实现的事务管理,但需要注入数据源 / |& |' ?; J3 b8 |1 ^- G
7 e, |7 W2 C5 E- `2 i) {) e! ]+ O1 P' z$ t0 w: J: g
2.5 事务监控所有的方法(事务加强)
+ c& e4 ~: m) V) E7 C1 m. a! s# }0 Y. R R- l/ z+ C) L8 w$ B
6 @4 t9 N* Z4 c7 G7 v0 W/ {
' ?$ K j7 N# Y( Q- k) q9 J, z
' d% D, A$ K$ W9 ?& ^1 h1 K7 f2.6 定义切入点
* X, ~' `7 @7 H2 s7 t$ \
! D8 m; G9 B) G& P
k6 t" Y5 h! V$ O; ~6 |% f' c/ c( l3 {8 c' h7 b
( Y3 I; l$ m: d. S
2、使用注解实现事务管理: 1.注解@Transcational (可以在类上,也可以在方法上) 2.在配置文件中同样需要注入dataSource和spring的事务管理 3.使用注解的方法来追加事务 注解驱动
* _" } V5 V) {2 @
I8 E7 k! l$ c7 \9 W如何在Spring中使用Hibernate的事务:
$ K- \* D8 ^% O" i, o
. m7 c, s' M) N% z9 S. [) i7 }
5 ?- L5 ^6 m) t- B' q/ ?
/ O- b# j9 K4 {2 ?
如何在Spring中使用JTA的事务:9 Z; L) B4 a: i
* ]; x; n3 U/ R! K: c |