Spring
$ Z3 s+ i" A+ X# p" w: w# H, l- 是什么?2 Y P0 k8 y u! e5 U2 b
! R& N) D3 J& `/ e6 Q9 V
Spring是基于JEE的轻量级的应用框架 ' ]* P- j. G" T( `! H9 v% N. }
- 有什么?
' {% C$ L3 I7 m; h" c+ T' C* J/ y8 H) [/ h$ s. A
r# F+ v) D/ l4 ^
每个包的功能: Spring MVC:spring 本身提供的web 框架 WEB:集成其他的web 应用的框架,或者说是对其他web应用框架的支持。如struts,webwork JEE :集成一系列的jee的技术(对JEE技术的支持) DAO:封装了JDBC;(对JDBC的支持) ORM:提供了对ORM工具的集成(支持) AOP :面向切面编成 CORE:spring的核心包,提供bean的工厂和IOC容器 : K" _+ e# B' |! T
- 能干什么?
# e$ m; O$ l2 v( I4 ~6 k
5 r2 }' ~+ I# L7 Z K6 k9 j
把一系列的jee的技术有效的组合在一起形成以良好的系统
) }% P) ^: U! P4 a8 X- 怎么用?
/ W" w5 l! m' ^1 Y, O& ?" G
' D- {7 c- M6 W8 }' n s- 搭建web工程,引入spring的jar包& j: H$ b% s F. b }4 [
- 在web.xml中添加如下配置
. X0 f" g M4 E4 u: d3 {% o2 _. W: o
$ N7 K/ A8 D9 y5 u8 H" k: I
: Z0 X& n! S& P6 y7 D3 B [
contextConfigLocation+ ^1 v/ e0 N; {# T: D& \
classpath*:applicationContext*.xml) ~7 h8 l2 s/ v0 ?6 h( \
5 B2 f- L! X. r7 W1 \' k, B. I
$ R1 M# a4 P" E# d8 i struts2, f1 H$ U, K3 T6 Z- T x8 w
0 f! O9 J* \9 F# i
org.apache.struts2.dispatcher.FilterDispatcher
( U0 I4 @5 c* w) k) E
) j! W& O5 x! D / H& i7 s6 U( Q7 ~. C
; X2 S- s+ n. w
struts2
( f2 g& `7 n* h8 l5 O /*; q5 Z4 q) l7 o3 B# D
: e3 Z- v% @0 c" f, p6 D0 o9 Q
3 D) A+ v7 F+ o8 @- @
9 ~1 z! D t& u p org.springframework.web.context.ContextLoaderListener
2 s7 e' B& u2 s1 o/ u( M
1 e B3 a* N; B( A' M - 部署; M' O6 s$ b2 R
4 U! h, `+ C3 Z% A- b" F l
8 T; ]9 Q0 ~" N- Z. a& G
, H8 X4 d& X' C( g* R+ |6 v! a/ I0 c% i. F1 ~% x
- 容器和bean3 C% | g1 w2 m. t b/ ^7 ^8 k) ]
Bean :是指受spring的ioc管理的对象称为bean 容器 :(与jee的容器类比) Jee :提供组件的运行环境和管理组件的生命周期(不能单独存在) Spring :提供bean的运行环境和管理bean的生命周期(可以单独存在) 2 w" b6 ~4 b! B4 Z
* C$ v& V0 F/ [& F, y5 _3 ?
- DI依赖注入
, t( @9 W9 b7 l7 C! F7 S
1. 应用程序依赖spring注入所需要的对象 IOC和DI是对同一种事情的不同描述 2.setter注入: 在配置文件中将接口的实现配置为bean在应用程序中注入bean 例如: 在配置文件中
3 M5 d# U8 h+ ?2 g+ a3 P7 R5 t# {% B: I9 P* F! `
4 i0 f8 R2 ^* H2 G1 S3 `+ n' y& j3 x
在应用程序中 Public DBDAO dao ; Public void setDao(DBDAO dao){ This.dao = dao; } 3.构造器注入 - E1 B4 \4 L! l; Y; |4 ]
4.ref 表示参照其它的bean 在参照的过程中一定要注意死循环 5.自动装配———–〉no 自动装配根据名字来匹配相应的bean 尽量不要去自动装配 6.lookup注入 7.singleton 1.单例模式是整个的jvm中只有一个实例 2.spring的singleton是指在spring的容器中只有一个实例 一个生命周期中只有一个实例 8.DI的优点: 1.程序被动等待,强化面向接口编成 2.切断了对象或组件之间的联系,使程序的结构更加松散,运行和维护更加简单
. ?7 v% ]( \! a0 e, `$ p3 I- Aop面向切面编程3 }/ f* w0 w; B7 H5 y- z/ z
' ]7 A% X; w, i' i8 Z
1.AOP面向切面编程 一些较好的模式或者是示例—-范式
; j6 A3 v: _6 I M0 m+ U" j8 m 切面:一个切面代表我们所关注的一系列的共同的功能点(模块之间的共同的功能点) 2.AOP的思想: 主动—->被动(追加功能)1 _/ G( p0 f Y& m. w
3.AOP 的概念
. c2 c* M6 Q( t( }" @ 1.切面 :我们所关注的功能点 2.连接点 :事件的触发点(方法的执行) 3.通知 :连接点触发时执行的动作(方法) 4.切入点 :一系列的连接点的集合 (连接点的模块化) 5.引入 :扩展的功能 6.目标对象 :包含连接点的对象 7.aop代理 :实现机制 8.织入 :把advice和目标对象连接起来 4.AOP的事件机制
0 L+ W- H0 G, @. g+ q$ @ 1.通过切面找出一系列共同的功能点 2.找到目标对象(在标准的spring 中 接口的实现类为target) 3.找到切入点 4.确定连接点 5.通知spring AOP,查询xml文件,通过代理找到advice。 6.由aop代理来实现动态织入
% W2 h8 \; a' i+ i6 e5 Y @3 ^+ e) E9 ]3 T% s# ]9 i
* ~/ r% m. \% d: c) d! ~
@/ W l0 B4 _0 P q
0 x V1 m) |# I: f0 k- F0 E4 f \
]: \. A2 O9 X: U! N8 m4 k0 f
( p0 n5 p0 r% Q8 E& Y+ E' N5. AspectJ
! r o4 y8 Y4 ]. d 5.1.在xml中配置比较烦琐
" v' u0 A: X) x- z% n 所有的入口必须从一个代理(ProxyFactoryBean)开始# {" E$ f, h4 w; p# r) s
# X: \3 O! W5 h* o+ B / j* q) ~ `8 G1 h, P, V% [
# P/ X% E% P- t1 M5 g, r7 O) D! |3 `
8 w+ c9 k3 \5 d0 I
& f% A8 t4 f+ K4 s3 |7 J8 o: C; k) W
, V' w. b$ I7 r: v c! h
: G' T( h& ]2 [expression=“execution(* com.javakc.aop.MyTarget.t*())”/>
' o' ?7 T# ^( g1 x3 w
1 Z; l/ @! q; e7 L
* v9 k" `- `5 P! d. m/ x) J
% O: i& S3 Z( E* K$ u: P , x: [+ e7 _/ ^: G/ [$ @
2 a. ?. C* L0 q1 g0 \
5.3.使用注解的方法相对简单! p9 o5 m1 F3 i$ @4 ~
@AspectJ的基本语法* {( ~8 x* n1 I5 B% b7 c2 ]: d
1.@Aspect声明一个切面,将一系列的共同的功能定义成一个切面1 P5 A* Z0 z! L: s% [* k
直接在类上定义@Aspect; L* d1 ~. p+ ~) [) S* g
2.@Pointcut声明切入点# q6 K, N# ~2 \/ O
2.1、用一个专门的类来定义pointcut,类中的方法名就是该pointcut的名字
" @: ^) B9 _2 n% ` E 2.2、可以使用匿名的pointcut
* A: v4 Z% M+ S, q3 H' N 2.3、执行切点的几种方法" D! t8 y! b+ x2 L( f8 {1 ~
2.3.1 execute(public * 包结构.*.*.(..)) 可以指定到具体的方法
|+ g f a4 h! o4 c, T# k 2.3.2 within 指定到包,不能指定到类" p0 X8 S9 p6 t$ K
within(”com.javakc.spring..*”)
# E! x: {+ V$ d2 X2 i 2.3.3 this 指定到实现接口的所有的实现类
4 V& O8 f6 A3 X4 D9 j 2.3.4 target 指定具体的实现类
/ S( M, q# D- K# Z1 N9 T/ ^8 a% q9 { 5.4.advice的五种类型的示例* U3 w; W6 r0 C- I2 E2 h, i
客户端必须从接口走才能得到监控,实现想要追加的功能& q7 }7 V m4 n8 r7 k
5.4.1.@AfterReturning(pointcut=”” returning=”retVal”)
4 V) j' Y, x6 i* O0 Z, V 追加的方法的参数名字一定要与retrning的名字相同
8 M! e5 }. J: q: z% T. ~: T' k6 {1 [ 在注解@AfterReturning中必须加上pointcut和returning两个参数+ i L; f& \) Y N6 I! u
pointcut指所要监控的目标对象的方法! y) |& S# @" b+ O$ H7 ^& G- l
得到目标对象的方法的返回值,来作为参数,进行下一步的处理,参数没有顺序,按参数的名字进行匹配0 ^) ~. O0 d1 d2 d, E, i8 F) Y
完成追加的功能6 }( h; T1 `4 \. }9 X0 L, Q
1 定义一个pointcut,通过方法名来作为pointcut的名称来引用2 ? |* B4 S; H+ n0 F
(1).@AfterReturning(“com.javakc.spring.schemaaop.TestPointcut.t4()”)
" J: {. u) b; k& @% I! `+ B$ r: b (2).
! l# b Y8 m/ E& @* B) Z, N& T$ S 2.直接引用匿名的pointcut
6 j% x$ p( }" z9 o7 u, ^# B7 y (1).@AfterReturning(“execution(+ U, X3 [3 H( g0 ^6 y
* com.javakc.spring.schemaaop.Api.test4())”)7 v; x# E0 ?5 [7 Y6 Q
(2).@AfterReturning(pointcut= g" v2 g/ u- \, ?" F- k. \* A
“com.javakc.spring.schemaaop.TestPointcut.t4() &&& q# r C0 M* U# W8 T
args(str)”, returning=”retVal”)
- M& G; L9 q @" b- \! J @AfterReturning (pointcut=”com.javakc.spring.schemaaop.TestPointcut.t4() && args(str)”,returning=”retVal”)
) ]: ~+ ~7 `# i public void testAfterReturning(String str,Object retVal){ m! L' e4 ?. g& j: T% S# f( ?: y
System.out.println(“afterReturning1=>”+retVal+”=>”+str);
$ G0 c' ~( Z H4 r& W0 }' @ }
1 N; G$ n' l1 O9 q. l4 Q1 V 5.4.2.@Aronud
* a4 I' }5 ?8 Z" C0 O% [ 注解@Around环绕追加功能;
2 ]4 w. b, c$ P/ s 在执行目标对象的方法的前、后追加功能;
, O2 |3 B. U% c, L$ c5 h 必须有参数;第一个参数的类型必须为ProceedingJoinPoint;
8 _" Y% h9 Q- c5 | 通过ProceedingJoinPoint的实例的proceed来调用所监控的
+ n% A j0 U- L4 b 目标对象的方法
" \6 t. P8 j. f F" [9 U, _ 1 定义一个pointcut,通过方法名来作为pointcut的名称来引用
" d' ? \" `% l- D. s (1).@Around(“com.javakc.spring.schemaaop.TestPointcut.t1()”)" s& s& j' q* q8 I
(2).@Around(“com.javakc.spring.schemaaop.TestPointcut.t2()% v" S+ x, S9 h$ c+ p9 t6 o* C
&& args(str)”)2 H. i& v+ [+ ^ e0 i+ S0 r" |
2.直接引用匿名的pointcut
- O `5 y7 o/ j8 h (1).@Around(“execution(
* c# X/ T5 H$ }" f+ S: K * com.javakc.spring.schemaaop.Api.test1())”)
0 [- @7 a, D2 C3 R3 h* \2 V (2).@Around(“execution(
) U& J4 P/ |6 w2 L0 }% ?# [2 A * com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)
! i$ D: [$ H) P. n/ U" Z/ W // @Around(“com.javakc.spring.schemaaop.TestPointcut.t2() && args(str)”)2 y( C% G7 [6 ^& F: i7 l8 A
@Around(“execution(* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)/ k6 s3 Q- r: Q
public void testAround(ProceedingJoinPoint prj,String str) throws Throwable{
- t$ v: j6 V1 c: C- B% y System.out.println(“around1==========before1pointcut==>”+str) q+ H; I: N( V: I
Object obj = prj.proceed();$ c8 k: T' Z; }! g9 a# L
System.out.println(“around1==========after1pointcut==>”+str);
6 N8 Z( r2 K- G: { S+ D; R }/ R& e- R d% x! I; e
5.4.3.@Before
5 o& ~8 i' I" p; i 注解@Before在执行目标对象的方法前追加相应的功能
% g. \5 m2 n" q5 Z( g+ k' h; |* k 1 定义一个pointcut,通过方法名来作为pointcut的名称来引用
7 O, k& }" A X (1).@Before(“com.javakc.spring.schemaaop.TestPointcut.t1()”)
0 k6 }. L$ ~8 x6 w$ I (2).@Before(“com.javakc.spring.schemaaop.TestPointcut.t2() && args(str)”)
& ^1 s5 S% y, s. m0 ^7 } 注意args后的名称与参数名相同8 r( t" m9 |0 b3 x/ ^$ z x
2.直接引用匿名的pointcut6 D/ X2 l8 j+ e5 y
(1).@Before(“execution(* com.javakc.spring.schemaaop.Api.test1())”)
0 y8 c1 x" J4 U7 v (2).@Before(“execution(* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)5 q* }, A5 B! ~1 w
注意args后的名称与参数名相同
" h) x5 N8 z/ P! r/ t, f // @Before(“com.javakc.spring.schemaaop.TestPointcut.t2() && args(str)”)
0 U! @1 H+ ^4 X' v; W4 G @Before(“execution(* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)* n* \$ d1 D# j5 u/ Y6 t2 V7 o
public void testBeforeParam(String str){
7 G8 B2 @( p! b: ]( n System.out.println(“before1=param=>”+str);8 k7 Y2 F3 U& ]9 Y8 A
}
1 \% N5 v# I* c6 c5 I$ b 4 n2 Z+ w9 n! R4 P* f: n
5.4.4.@After
9 } d4 P/ m6 B1 y 注解@After在执行目标对象的方法后追加相应的功能! i! p4 @% s; P- K5 B
1 定义一个pointcut,通过方法名来作为pointcut的名称来引用3 j% U; O3 N$ I. [
(1).@After(“com.javakc.spring.schemaaop.TestPointcut.t1()”)
5 V* [* d h; X i5 Z% O9 g' a: C 2.直接引用匿名的pointcut
9 E U1 ^/ m9 i (1).@After(“execution(* com.javakc.spring.schemaaop.Api.test1())”)
: C. n( K# U3 E' Z( r s @After(“com.javakc.spring.schemaaop.TestPointcut.t1()”)+ t. V$ k/ b3 R5 I! Y
public void testAfter(){# h" ~ u5 w2 U) U" Y
System.out.println(“after1== >pointcut”);
% s, _4 g& L; Z, ~8 V8 R }9 z( T: m+ f, r2 B8 k
5.4.5.@AfterThorwing9 Q3 _5 o! j* ?& y
% O! ~+ [6 i. f& j7 @" Z
% Z& {# _% z% R, \
- 描述一下spring中BeanFactory和ApplicationContext的差别
! `! L: ?% l2 F5 U1 T5 Z
1 P2 s9 [& d# d0 j' h
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”);
& F7 X; j! @7 D( m& ^& i- 谈谈spring对DAO的支持3 J! e: `3 [6 ?
" [/ ^- r7 d/ G/ k( _
Spring提供的DAO(数据访问对象)支持主要的目的是便于以标准的方式使用不同的数据访问技术。
3 q, X- u% X; M6 f( q 简化 DAO 组件的开发。
4 ^: |) d, m% \9 [$ t6 W' e; ^# xSpring提供了一套抽象DAO类供你扩展。这些抽象类提供了一些方法,用来简化代码开发。
. P3 @9 j% w8 y. w$ T% Y2 H) P IoC 容器的使用,提供了 DAO 组件与业务逻辑组件之间的解耦。所有的 DAO 组件,都由容器负责注入到业务逻辑组件中,其业务组件无须关心 DAO 组件的实现。
3 Z* v. `3 G& p1 V 面向接口编程及 DAO 模式的使用,提高了系统组件之间的解耦,降低了系统重构的成本。
3 e8 F% f% E# x B. t/ l3 o$ o 方便的事务管理: Spring的声明式事务管理力度是方法级。
. c0 U9 \) f3 X7 W I2 c& [3 K$ P 异常包装:Spring能够包装Hibernate异常,把它们从CheckedException变为RuntimeException; 开发者可选择在恰当的层处理数据中不可恢复的异常,从而避免烦琐的 catch/throw 及异常声明。" {$ K3 f# t9 }: c. V5 n' `
+ i% J* V" u7 b# S
% z* F, n% v# E0 d. N4 d0 X- 谈谈spring对hibernate的支持
' Z- Q& }0 N% q
" }3 a( x8 z+ K" z
在所有的 ORM 框架中, Sping 对 Hibernate 的支持最好。如 SessionFactory 的注入、HibernateTemplate 的简化操作及 DAO 支持等。另外, Spring 还提供了统一的异常体系及声明式事务管理等。3 W. o- b1 v" f/ i( O0 N- y# u, u
一旦 Hibernate 处于 Spring 的管理下, Hibernate 所需要的基础资源,都由 Spring 提供注入。Hibernate 创建 SessionFactory 必需的 DataSource ,执行持久化必需的 Session 及持久层访问必需的事务控制等,这些原本必须通过代码控制的逻辑,都将由Spring 接管 ataSource, SessionFactory, TransactionManager等,都将作为 Spring 容器中的 bean。将这些bean 放在配置文件中管理。+ W1 K0 I. v1 B" Q3 K, Q+ O# a
1、通用的资源管理: Spring 的 ApplicationContext 能管理 SessionFactory,使得配置值很容易被管理和修改,无须使用Hibernate 的配置文件。详细配置如下:
1 p' \" ^1 ~9 Z/ m4 q9 y T( D5 W2 g0 ^
class=“org.apache.commons.dbcp.BasicDataSource”>
" u& R U, p# c$ s" |
6 \& A Z) X# A% Y oracle.jdbc.driver.OracleDriver
; T2 \, \. U1 v1 n
( \6 L, N8 p1 ~) f
o% f! Q$ s! \2 y5 p8 h5 s8 C jdbc racle:thin localhost:1521 rcl
" S p+ M1 h( i& x: ?
7 \0 w4 ~6 J/ N+ }/ a- _( m1 i 0 o* u1 b" L8 X
javakc2% ]. S- X. `" k$ y$ w7 n- C
9 I$ z) H5 |: f. O. q8 o8 _
: r% P' Y5 n7 H6 ` javakc2
! p- C0 V8 R1 l* D# v - B1 T9 v/ J& c3 X- Y
$ ]& k$ _# p* o6 p# S" A5 ?
6 ^7 `6 `7 v+ r! A, s" t. n class=“org.springframework.orm.hibernate3.LocalSessionFactoryBean”>5 G( R& J. O) v3 o! d- R9 y
4 k9 \5 R* p# R k1 `$ `1 E" w/ F
; ]5 M; b' X& @0 B& K 3 u; L& T2 n$ x6 x1 T- P4 G
com/javakc/spring/h3/UserModel.hbm.xml/ K; ^' H# X) E5 c$ O
. c; N; E R! q; h5 F& M
3 }7 `5 a7 W- V3 \. |! X) ^) x! r
, C, D( t- Q6 o+ Z" B9 e 3 ?' \8 g4 @9 N/ {! l7 u" h& f
hibernate.dialect=org.hibernate.dialect.OracleDialect" E- d4 ]) k* p n9 e, w
, R% W* E* I( Z8 _, V
( z' q4 Q: L! m& i9 ?" C" G
4 J8 Z/ T8 x- w; p W# z 5 m9 q, d w) d8 y3 M
. B& Y) E- _- Q, ]' u 0 X2 @ a2 X' w o
如果需要使用容器管理的数据源,则无须提供数据驱动等信息,只需要提供数据源的JNDI 即可。对上文的SessionFactory只需将dataSource的配置替换成 JNDI 数据源,并将原有的 myDataSource Bean 替换成如下所示: class=“org.springframework.jndi.JndiObjectFactoryBean”>
7 X7 u) Y; o: t: Q 7 i0 r. C0 X% Y
java:comp/env/jdbc/myds ]! [7 H! o4 Y3 v w8 L
% W1 L4 V/ _6 ^8 w r0 ~
2、有效的 Session 管理: Dao类继承HibernateDaoSurport后,Spring 提供了 HibernateTemplate,用于持久层访问,该模板类无须显示打开 Session及关闭 Session。它只要获得 SessionFactory 的引用,将可以智能打开 Session,并在持久化访问结束后关闭 Session ,程序开发只需完成持久层逻辑,通用的操作则由HibernateTemplate 完成。 3、统一的事务管理。无论是编程式事务,还是声明式事务, Spring 都提供一致的编程模型,无须烦琐的开始事务、显式提交及回滚。 建议使用声明式事务管理,Spring 的声明式事务以 Spring 的 AOP 为基础。可将事务管理逻辑与代码分离。代码中无须实现任何事务逻辑,程序开发者可以更专注于业务逻辑的实现。声明式事务不与任何事务策略藕合,采用声明式事务可以方便地在全局事务和局部事务之间切换。 Spring声明性事务有两种配置方法,一种是xml配置: ) A, k/ o8 ^5 S) } l
. }* E# E: n" f* v
8 B9 h7 R6 t6 K
& d+ g4 p" d: l* o% U
7 W% m% w# n- n8 P
, Y5 k% v1 L( ~, E1 F/ A x
6 j( |# a' ?2 r0 s1 W" ~; T
# D9 i5 [' o9 p" _& x7 F7 ?5 q1 ^
" f( W- F) s% x' q6 y+ B$ c
) B# U, W7 Q5 r2 F, g7 c4 t
, ?$ C. J* S$ S c / U' p; j' ?. `' |
# z+ w. N- ~! K! F: }% `; p 7 |; q2 S) Y) r3 @5 }
另一种是通过注解,在需要添加事务的类上注明 @Transactional - P' l/ \9 } z3 w
Spring2.0之前事务的写法
7 A8 T4 P' y: W3 f' p
4 ]$ U6 P6 _4 h3 S
; O; q2 V- i' Q6 h! E3 I class=”org.springframework.transaction.interceptor.TransactionProxyFactoryBean”6 Z2 x5 }5 x6 w Z+ w( g0 m7 T5 z+ D5 g5 d
4 H0 S- @! _) F7 K8 K* @- a1 ] abstract=”true”>
+ N2 E- C4 z' v3 Y/ i6 O7 W
$ D/ |, Z. u8 ^6 O3 z9 e8 W/ }- t: w6 F7 C- M# s5 @$ l
8 Q- {. I4 A3 y) N7 i1 ~. b
1 O7 e' i. J. S% o( D: W PROPAGATION_REQUIRED,readOnly8 ]. _5 K/ g" Y, E: t
6 O& ]$ l: ~) @1 b: l8 V PROPAGATION_REQUIRED1 u% ^8 T3 U/ g, V
$ R6 ~4 d/ s/ \5 I# U6 ^( d6 n
V( D; M5 g9 x1 S9 C% k# M/ F0 f) y, L9 [; `( J
' i& ~4 j3 `8 x/ Z |
3 q0 k5 j- u/ u2 M P# O! Q- ?
+ P# x$ Z; _2 D4 g6 p- 谈谈Spring对事务的支持. P& `, a3 m/ \1 ^1 |2 k9 o
+ K9 T3 ?; q- E) w8 C" A
4 O \6 _- m$ k) m" @ P2 P! A( B
1、声明式事务管理: 1.流程:由客户端访问—-aop监控—-调用advice来追加事务 2.做法: 2.1 在配置文件的头中引入xmlns:tx 和schema的文件 2.2 2.3 注入数据源
" O* u) }, h2 w7 p! d4 ^
~% V( k5 u7 z% x6 m: r. |$ a) \9 O
# X" O2 e/ A$ X* Z" Q( I
) u1 Q" j$ N0 V t' Z
& D4 C+ G: @* S. x, H( @- A
2.4 由spring实现的事务管理,但需要注入数据源 ) j7 V2 L" c! Z( C
6 {1 Z6 C/ P* Q( X4 t( e8 o
) j; u2 x# j+ L2.5 事务监控所有的方法(事务加强) * y# ]3 k* ]) M: m4 |
- Y' e; n8 R* ^- `5 p( c5 R
& y l9 G" F) r d) F3 g( Z$ C7 ^ E1 P
& U3 g& |7 w" e. p* G# Y2.6 定义切入点
- T8 D1 q" `, v0 |" R9 I' j+ N6 V m( Y8 r: ~1 i' ]7 D( ]
% @+ M% e+ o, Y( v7 ~" W! |& N3 A, g
1 X. H# |) C# ^0 s" D. F1 d& O" e. {5 b+ |1 M+ a$ Z; u3 X
2、使用注解实现事务管理: 1.注解@Transcational (可以在类上,也可以在方法上) 2.在配置文件中同样需要注入dataSource和spring的事务管理 3.使用注解的方法来追加事务 注解驱动
+ O) t' [. H% a9 v; Y$ m3 [4 j1 ?; d: S) D I7 h
如何在Spring中使用Hibernate的事务:
: w5 }/ W; o/ g$ Y 8 Q5 V$ @+ u: b$ G: P& A5 Q
' `( @! c" \2 Y3 a" A
8 M, Z, ~. H+ M+ X' u
如何在Spring中使用JTA的事务:
+ T# C, G) j |, G: b 1 w( X q: {0 V$ P
|