Spring
/ n; {: b& A8 M; n- 是什么?% B% b/ j: p% G: b' i3 \7 {2 u
8 V9 O, y( ^. Q7 Z$ N4 B1 h
Spring是基于JEE的轻量级的应用框架
1 B0 R5 l! l1 I# `, `3 g( H! h- 有什么?" g* c6 O9 R9 v8 v
% q6 L9 V3 r9 d7 |% ~ 8 c. k4 T: ]9 R- m' c
每个包的功能: Spring MVC:spring 本身提供的web 框架 WEB:集成其他的web 应用的框架,或者说是对其他web应用框架的支持。如struts,webwork JEE :集成一系列的jee的技术(对JEE技术的支持) DAO:封装了JDBC;(对JDBC的支持) ORM:提供了对ORM工具的集成(支持) AOP :面向切面编成 CORE:spring的核心包,提供bean的工厂和IOC容器
: h) Q+ r* n, B9 x3 J- 能干什么?
) i: O) \8 \" D l5 L* }/ f `6 h* G9 k+ }( u' _
把一系列的jee的技术有效的组合在一起形成以良好的系统 3 b8 p! e- U9 h( Q
- 怎么用?
$ ?# R. E1 c) D$ [% h4 \
, U8 x6 J0 y" z4 u9 Y0 F) t- 搭建web工程,引入spring的jar包, k2 v" k1 T0 N& m& {
- 在web.xml中添加如下配置7 V: \" k9 v) o; d" }$ O8 T e& _
1 V% s- H7 P7 r4 T, \ e
" l `* b% m4 x
3 F) r! I" D" u& ^+ k) a1 N# f
contextConfigLocation
2 C n& r+ d5 p& }1 a2 g classpath*:applicationContext*.xml
" H/ Q! U2 u9 e' g9 d 3 K, U/ }9 |5 D$ L% I# Q; ?
4 G5 F6 h1 ^0 J6 E struts2
~$ c) @' J: e
' G; U& W, ~3 l8 ?3 o1 D# I7 C org.apache.struts2.dispatcher.FilterDispatcher3 Y, A9 \) V: X( j6 E$ D
! L' R8 X# d- [2 p* c7 `
; j* r8 a& \. t
3 A* S. m3 p' s& e; { struts2
/ p, N2 x6 h# w# d /*
5 J8 D A$ r+ |; P9 u% g 5 c# r4 K2 S( S: v
1 ~/ K j7 `. N( q
6 W8 N; d% U6 Q J* P# J" X ~ org.springframework.web.context.ContextLoaderListener: k, ~" a( a6 f4 E7 e
; j9 R$ K8 a: K0 k! S - 部署, ?: H' k- \! c" u& f
3 |/ S% ]9 G$ G( |9 ] 4 T0 b6 m$ `( Y
. m/ Z+ d6 ]$ @& W1 M, _& i2 u7 N
6 p; I& [4 V0 b$ B# }5 u q3 d& B
Bean :是指受spring的ioc管理的对象称为bean 容器 :(与jee的容器类比) Jee :提供组件的运行环境和管理组件的生命周期(不能单独存在) Spring :提供bean的运行环境和管理bean的生命周期(可以单独存在)
" l$ a+ E j8 _' }/ L1 H: B) g
8 M' t: D8 h S5 M4 \) Q; u7 v- DI依赖注入( R6 ?: u1 ^3 a0 `! W8 R& S
1. 应用程序依赖spring注入所需要的对象 IOC和DI是对同一种事情的不同描述 2.setter注入: 在配置文件中将接口的实现配置为bean在应用程序中注入bean 例如: 在配置文件中
/ s& T9 m8 r/ @$ p# a; E7 w) _6 G5 A8 U: y
: S5 A8 F( T3 S0 q在应用程序中 Public DBDAO dao ; Public void setDao(DBDAO dao){ This.dao = dao; } 3.构造器注入
6 g* G2 Z# { w9 @( u% Q: P& F4.ref 表示参照其它的bean 在参照的过程中一定要注意死循环 5.自动装配———–〉no 自动装配根据名字来匹配相应的bean 尽量不要去自动装配 6.lookup注入 7.singleton 1.单例模式是整个的jvm中只有一个实例 2.spring的singleton是指在spring的容器中只有一个实例 一个生命周期中只有一个实例 8.DI的优点: 1.程序被动等待,强化面向接口编成 2.切断了对象或组件之间的联系,使程序的结构更加松散,运行和维护更加简单 : D' y: Y9 O0 Z" v0 ^& _
- Aop面向切面编程
1 N7 d8 t4 e, g6 t6 J. A. Z% l/ i8 k2 [. d9 x+ F' \' U Z& L3 W
1.AOP面向切面编程 一些较好的模式或者是示例—-范式6 ^+ D% |- k J& |- M7 M
切面:一个切面代表我们所关注的一系列的共同的功能点(模块之间的共同的功能点) 2.AOP的思想: 主动—->被动(追加功能)
1 L1 I9 N& \3 D) ?$ A/ a, p 3.AOP 的概念* \+ S( L# k5 @5 n: e8 V: n( T
1.切面 :我们所关注的功能点 2.连接点 :事件的触发点(方法的执行) 3.通知 :连接点触发时执行的动作(方法) 4.切入点 :一系列的连接点的集合 (连接点的模块化) 5.引入 :扩展的功能 6.目标对象 :包含连接点的对象 7.aop代理 :实现机制 8.织入 :把advice和目标对象连接起来 4.AOP的事件机制
: _, M& Y+ `$ k 1.通过切面找出一系列共同的功能点 2.找到目标对象(在标准的spring 中 接口的实现类为target) 3.找到切入点 4.确定连接点 5.通知spring AOP,查询xml文件,通过代理找到advice。 6.由aop代理来实现动态织入
+ b, D! t1 v, V% N
+ y" J: a% ?- F4 P# C
8 j: T' Y. H, p! f5 s* n5 i* z8 m: v2 F! B* y
- W1 R, S7 J) }( g& d
0 N) Q- w) c5 k" Z6 I7 R- s4 o6 C
; b# b- t" J! O9 m9 _5. AspectJ! }. [. C! e; `$ M% a" N% h6 @+ u
5.1.在xml中配置比较烦琐
' V- l8 X$ e5 q2 ?1 I# }- g 所有的入口必须从一个代理(ProxyFactoryBean)开始) Y3 h8 C) D: ^9 M+ U6 {. C- i4 i
( U$ @1 J N4 V' Z! P: g; g+ e! {% W
6 J! S8 x; b5 }) X- W ! ^, ]2 R. E3 Z6 P% V/ T
, `( O/ }0 N2 B8 J
* [4 h1 J4 w, ~3 t$ P" K
% K2 K% I' D0 D# J, Q; A$ k
% n' P9 y! c9 ]# Y9 N# i p' K! }9 o- V* ^$ }
expression=“execution(* com.javakc.aop.MyTarget.t*())”/>
/ p C7 v6 l' f7 G+ K* D; P. r/ N
6 h! X* R& Y0 `$ }( b! i
! V$ \9 Q8 _2 ]! D ^7 \" I( A - I7 C2 G0 }) e
0 d. r6 O; h* c( c+ a! y. W1 l$ f
% {5 T; m) q0 Z- A" W/ X5.3.使用注解的方法相对简单
" Q$ k6 k7 T( h# X9 } @AspectJ的基本语法- j! H6 I- k1 z3 j' ]- P
1.@Aspect声明一个切面,将一系列的共同的功能定义成一个切面& {6 f. d* J: O- u, b6 I9 @
直接在类上定义@Aspect
: ` [6 l) T4 \3 q+ J 2.@Pointcut声明切入点
- k% Y2 L; \0 j5 _9 L& L, ` 2.1、用一个专门的类来定义pointcut,类中的方法名就是该pointcut的名字) z9 `" Z. ^' H8 N: u
2.2、可以使用匿名的pointcut
* z& ]' _% F% W+ U4 w- I7 m 2.3、执行切点的几种方法
0 F( D# @" g5 V+ U 2.3.1 execute(public * 包结构.*.*.(..)) 可以指定到具体的方法
$ c7 K5 u/ a7 P$ s5 K: ?; T 2.3.2 within 指定到包,不能指定到类
7 g% s3 ]1 S* d& f9 i6 @, I, n" d within(”com.javakc.spring..*”)
7 D$ o2 K4 N4 M% o" U 2.3.3 this 指定到实现接口的所有的实现类
7 f8 o; {) E/ @0 a8 S 2.3.4 target 指定具体的实现类
5 l6 f* U8 Z. T Y6 d 5.4.advice的五种类型的示例) O5 ~9 S& K- e" E
客户端必须从接口走才能得到监控,实现想要追加的功能; g) z' c! p! S6 N; ]3 g x! P6 i
5.4.1.@AfterReturning(pointcut=”” returning=”retVal”)5 v6 |0 |8 u T d8 J
追加的方法的参数名字一定要与retrning的名字相同
+ U! Z1 g8 a* k 在注解@AfterReturning中必须加上pointcut和returning两个参数1 k! t9 I% Z/ X' `
pointcut指所要监控的目标对象的方法; X7 R+ T8 o8 b( y
得到目标对象的方法的返回值,来作为参数,进行下一步的处理,参数没有顺序,按参数的名字进行匹配
& f; ^6 T; ? N3 {/ @- o- Q 完成追加的功能8 C5 Q. \# Y. t& s, @
1 定义一个pointcut,通过方法名来作为pointcut的名称来引用# B$ J2 {+ [/ G1 w; i1 T# i
(1).@AfterReturning(“com.javakc.spring.schemaaop.TestPointcut.t4()”)0 \+ }& h7 I5 `& ^
(2).% M* w' r( W# c( b; z7 d0 j# x
2.直接引用匿名的pointcut' Y3 {( Y3 v( w1 n t. H
(1).@AfterReturning(“execution(
; o7 Y! ?8 f! ^- X* k6 r/ b; P * com.javakc.spring.schemaaop.Api.test4())”); f1 U# Y8 }1 x: V5 O% c
(2).@AfterReturning(pointcut=
" F( Y6 h/ n* B4 D9 y6 S “com.javakc.spring.schemaaop.TestPointcut.t4() &&
* f3 M* b* S5 u. i4 e, a9 u args(str)”, returning=”retVal”)
9 t6 A! O4 K! Y9 {+ H2 Q0 M8 C @AfterReturning (pointcut=”com.javakc.spring.schemaaop.TestPointcut.t4() && args(str)”,returning=”retVal”)
5 D! {+ S" [+ b8 M" }( K public void testAfterReturning(String str,Object retVal){
: }' y4 Q: ~& q7 \: O5 _# w7 l System.out.println(“afterReturning1=>”+retVal+”=>”+str);0 M1 L9 u& [8 _" Q' l3 A6 z$ l i: p
}
& u4 k* K' R0 ^& R) ~7 H 5.4.2.@Aronud6 N3 c0 p2 f1 V2 q9 A
注解@Around环绕追加功能;; c( K0 O, Q7 o- G8 V. T
在执行目标对象的方法的前、后追加功能;# ~9 A ~+ _( m U7 h
必须有参数;第一个参数的类型必须为ProceedingJoinPoint;
6 U5 p' g8 f- _$ @ 通过ProceedingJoinPoint的实例的proceed来调用所监控的7 g; |) L6 E5 q0 R9 f5 W3 a+ Q3 z; a
目标对象的方法
7 W2 Z* \8 u" L p, _" a) X 1 定义一个pointcut,通过方法名来作为pointcut的名称来引用
3 K( Q5 F( d% J& l2 S/ _ (1).@Around(“com.javakc.spring.schemaaop.TestPointcut.t1()”)
$ c8 k4 j7 H3 p+ ^8 a/ }& c4 R (2).@Around(“com.javakc.spring.schemaaop.TestPointcut.t2()
2 L8 |; {: y' m: P% M2 l && args(str)”)
5 g+ e; p- `' g1 Z 2.直接引用匿名的pointcut
" a% `0 l. b! J8 Y- ]3 m (1).@Around(“execution(
6 u6 @. E' i% g- P6 y Z, k+ K1 z1 X * com.javakc.spring.schemaaop.Api.test1())”)
4 X9 ], P1 x! X" ~, P U (2).@Around(“execution(
9 a1 `8 R" H9 J6 r * com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)3 j$ n6 a" G, E/ h9 |
// @Around(“com.javakc.spring.schemaaop.TestPointcut.t2() && args(str)”)
9 z/ a: G& d: s5 s" I! N @Around(“execution(* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)
% h. j" F+ D* [+ j2 G8 W* f public void testAround(ProceedingJoinPoint prj,String str) throws Throwable{
' M% ?9 d( ?& X% \: w/ q1 Z- b+ _ System.out.println(“around1==========before1pointcut==>”+str)' T6 l9 B/ g. J* g8 J* l
Object obj = prj.proceed();
; u8 p8 @3 B. F9 n8 w System.out.println(“around1==========after1pointcut==>”+str);
) [( h0 G; U; u W- Q }
, o* v9 d% R; Z 5.4.3.@Before
0 C' \: k1 p% a! z' |4 C: u& _7 [ 注解@Before在执行目标对象的方法前追加相应的功能
! m8 z' O9 D% K# E3 g* I# A! |. ` 1 定义一个pointcut,通过方法名来作为pointcut的名称来引用
) k; x7 A- e' B' h$ e (1).@Before(“com.javakc.spring.schemaaop.TestPointcut.t1()”)' @) y! M4 R) [: x
(2).@Before(“com.javakc.spring.schemaaop.TestPointcut.t2() && args(str)”)! v# ~ \% B% R0 g/ R7 `' d
注意args后的名称与参数名相同
" E- Q5 Z1 ~2 q/ v& g: B$ F" V9 l 2.直接引用匿名的pointcut
, F' ]8 i0 f! z (1).@Before(“execution(* com.javakc.spring.schemaaop.Api.test1())”)6 X, }6 W% J9 k0 i
(2).@Before(“execution(* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)
: G0 Z7 N- _; s' S; z2 `6 ^" ] 注意args后的名称与参数名相同; `% k3 V: R+ b2 E T3 n, t
// @Before(“com.javakc.spring.schemaaop.TestPointcut.t2() && args(str)”)
) \( `0 H0 M3 e. ` b9 L2 Q @Before(“execution(* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)/ z" x$ }: e( X. S9 n E( t
public void testBeforeParam(String str){6 P, T1 H4 T4 E4 V# b# N/ J' w# Z
System.out.println(“before1=param=>”+str);! y2 k, P# {1 o n
}
/ A# I2 I4 l2 ~ s3 p 2 i' m% K5 ^, s
5.4.4.@After/ _, D8 X) Z2 H/ [4 G5 Y& j
注解@After在执行目标对象的方法后追加相应的功能/ M2 \8 |! C% `& s# @9 ~) |5 l3 a! l8 G& M
1 定义一个pointcut,通过方法名来作为pointcut的名称来引用, u9 O" A8 F4 X% j3 K4 [
(1).@After(“com.javakc.spring.schemaaop.TestPointcut.t1()”)
9 y4 A! M1 r/ Z 2.直接引用匿名的pointcut
; r+ A- ^! Q' L# V, Y$ {' c (1).@After(“execution(* com.javakc.spring.schemaaop.Api.test1())”)
' i8 n' s/ r- X+ }' q4 @! G: ] @After(“com.javakc.spring.schemaaop.TestPointcut.t1()”)3 z0 ~) O( s% [ Q: p ~% n% X2 ]0 x
public void testAfter(){+ | p* g0 c& M9 M' Z
System.out.println(“after1== >pointcut”);8 b7 k+ v2 z- o5 X, e0 e2 X
}
/ O: W5 S2 p5 {1 v5 M 5.4.5.@AfterThorwing3 r: K% i1 Z+ T/ a" ` S& E
0 m2 g5 Y, u, p$ o- m/ B9 x% R1 y# P7 n; Q
- 描述一下spring中BeanFactory和ApplicationContext的差别
7 N6 k2 f7 C. i' p) e
( A0 b6 b+ D; I5 y" @
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”); . r1 E, I. o* W
- 谈谈spring对DAO的支持
/ O& m# N& J% P- O- O9 ^" P8 b1 H4 i$ ?
Spring提供的DAO(数据访问对象)支持主要的目的是便于以标准的方式使用不同的数据访问技术。
3 G) \) R$ n X) {. J* o. d7 }# R 简化 DAO 组件的开发。6 e3 [* S! o0 q8 W' |8 K$ ~1 S
Spring提供了一套抽象DAO类供你扩展。这些抽象类提供了一些方法,用来简化代码开发。
# a2 d5 e# R2 A2 ]" I- X IoC 容器的使用,提供了 DAO 组件与业务逻辑组件之间的解耦。所有的 DAO 组件,都由容器负责注入到业务逻辑组件中,其业务组件无须关心 DAO 组件的实现。
1 t1 I$ r: ]& D/ R+ [; ^ 面向接口编程及 DAO 模式的使用,提高了系统组件之间的解耦,降低了系统重构的成本。, H5 w5 z+ c0 s" i
方便的事务管理: Spring的声明式事务管理力度是方法级。7 h ^5 p0 `) G' z) X- F
异常包装:Spring能够包装Hibernate异常,把它们从CheckedException变为RuntimeException; 开发者可选择在恰当的层处理数据中不可恢复的异常,从而避免烦琐的 catch/throw 及异常声明。8 u7 g* `& B! V; P2 H+ q
N! @' @5 t9 v9 n3 r5 v
) u: s8 y/ y0 V1 A# q3 p- 谈谈spring对hibernate的支持
1 P. O% |' U7 c, `1 p5 f; G: Z2 Z
9 _/ a1 U3 f, ` u; P
在所有的 ORM 框架中, Sping 对 Hibernate 的支持最好。如 SessionFactory 的注入、HibernateTemplate 的简化操作及 DAO 支持等。另外, Spring 还提供了统一的异常体系及声明式事务管理等。
* L7 `+ g1 R, _' u( m) C7 d/ f 一旦 Hibernate 处于 Spring 的管理下, Hibernate 所需要的基础资源,都由 Spring 提供注入。Hibernate 创建 SessionFactory 必需的 DataSource ,执行持久化必需的 Session 及持久层访问必需的事务控制等,这些原本必须通过代码控制的逻辑,都将由Spring 接管ataSource, SessionFactory, TransactionManager等,都将作为 Spring 容器中的 bean。将这些bean 放在配置文件中管理。
: b- }: }0 R3 V3 U6 ` 1、通用的资源管理: Spring 的 ApplicationContext 能管理 SessionFactory,使得配置值很容易被管理和修改,无须使用Hibernate 的配置文件。详细配置如下:# m. x" R+ S* _2 M9 K
4 }# k+ y/ R7 h" Q) U7 s- J' t8 O5 L class=“org.apache.commons.dbcp.BasicDataSource”>
% Q; F/ I! ]3 e( D: o& g! f/ I 5 k! V, b, }$ F$ k
oracle.jdbc.driver.OracleDriver
" R6 N+ N- ^5 W- Y% T- t
) G7 N+ Z' M$ t
6 a6 i! L( b2 Z' Y1 X4 A a# o" H jdbcracle:thinlocalhost:1521rcl
! `: M% {7 a" w9 u. m & X7 t7 D0 I9 l' @& \
6 K. Z' a3 G0 D/ w javakc2/ e9 [5 U0 j1 _
6 o8 Q7 ]" ?" p
1 b) H/ {* Q! j8 b7 K; k8 V javakc2$ H* V: O: T8 t/ N) @" w
! C3 r `/ F5 ?7 `, S4 R
4 p0 I, I. j" J& M7 c* e( \
4 T# s; s1 o8 V; Y* P4 b n. \ class=“org.springframework.orm.hibernate3.LocalSessionFactoryBean”>4 n, D* _/ l; o# R6 s D
5 |$ i! k% c* M2 ^# b2 O8 r
- l! M$ \ Q/ n; L* Y
2 z( q3 d" Q5 P6 N U com/javakc/spring/h3/UserModel.hbm.xml
; \( M+ f1 v% |. ^ % e8 _& a7 i5 G' M; ~
7 }+ \6 C# w2 J/ U" o
) u- b1 _* a# `
9 g7 I/ i) O" x5 y u$ Y N hibernate.dialect=org.hibernate.dialect.OracleDialect
% d( s$ V' S& t F
L! D# A6 a# n' g2 ~ ( G+ a* F. t6 F6 M2 l3 I
# l3 q' [, h" B5 ^+ w Z
* M' Y; C$ C" l. D 2 b, g: y- t7 g4 t0 h
& O4 t3 J# }& W$ S 如果需要使用容器管理的数据源,则无须提供数据驱动等信息,只需要提供数据源的JNDI 即可。对上文的SessionFactory只需将dataSource的配置替换成 JNDI 数据源,并将原有的 myDataSource Bean 替换成如下所示: class=“org.springframework.jndi.JndiObjectFactoryBean”>( T k' v% M7 `% W/ }# [2 K# a
6 [& j" ?( {+ X7 {% U8 M) y3 `
java:comp/env/jdbc/myds
0 R4 F& D0 m( E. d9 H* v 1 Z1 m- k4 [$ ]7 ~. l; U* b0 O( q
2、有效的 Session 管理: Dao类继承HibernateDaoSurport后,Spring 提供了 HibernateTemplate,用于持久层访问,该模板类无须显示打开 Session及关闭 Session。它只要获得 SessionFactory 的引用,将可以智能打开 Session,并在持久化访问结束后关闭 Session ,程序开发只需完成持久层逻辑,通用的操作则由HibernateTemplate 完成。 3、统一的事务管理。无论是编程式事务,还是声明式事务, Spring 都提供一致的编程模型,无须烦琐的开始事务、显式提交及回滚。 建议使用声明式事务管理,Spring 的声明式事务以 Spring 的 AOP 为基础。可将事务管理逻辑与代码分离。代码中无须实现任何事务逻辑,程序开发者可以更专注于业务逻辑的实现。声明式事务不与任何事务策略藕合,采用声明式事务可以方便地在全局事务和局部事务之间切换。 Spring声明性事务有两种配置方法,一种是xml配置: 8 @2 |. H0 {7 ?
- I) w9 g4 ^5 e9 B
+ @# u! q$ V! s; `! U# u
/ v) f! w( \; Q- U
& B# _8 p5 Z- w2 e5 I& ~
/ ]1 u8 v+ D- }) T 0 K# h+ f" \, U2 @$ }6 }5 H3 s8 v
4 y, X. P1 E: u , x+ U* Q9 @ v! U% k0 S
* M0 p0 T& I0 n) @6 f
' g! w' v$ M- ?# `( {
; e5 `5 `. i4 o
6 u* `; f( e8 W; U& @' q# ?4 P
0 U1 \1 G2 c9 V: M' ] 另一种是通过注解,在需要添加事务的类上注明 @Transactional
( Y4 @/ E! @- N& J- {6 N2 zSpring2.0之前事务的写法 P l! k7 ^6 K4 C
& a- e) O# Q* U7 u) e% L! D
' s6 b- o1 S0 [6 F- }$ z2 ~" a class=”org.springframework.transaction.interceptor.TransactionProxyFactoryBean”+ O2 m4 K+ A( U5 e! h5 H( ]7 v
- F5 i4 n- l# {. { M
abstract=”true”>( F5 ~3 u U* x( R f8 [
3 k) l/ S$ I" d! o2 C1 @
8 m/ J" `% e6 k, S0 W3 q6 o3 y$ E1 y2 f% `: @! q" H
# w: M7 Z1 @! @- p+ _ PROPAGATION_REQUIRED,readOnly
' n: P8 d2 W( a0 @3 h7 w
8 {( ^) @/ B0 W( Q \$ d0 Y PROPAGATION_REQUIRED
7 X/ I' A: d! U3 k/ }; K
3 r0 D; |6 H* i5 o( f: n: J1 C, n. W0 Z
7 W8 {* I5 _/ ]& u$ W! Q
* S% e$ j9 g0 o; {
8 D" p5 a( p1 E* n& v; B! | | + m* n+ [; ^) W) Y8 A" F7 a! e
2 e6 A0 i. h' }
- 谈谈Spring对事务的支持8 z4 o2 o* i4 R% a" r! L2 e& r
7 N) \ {8 B( r
& ^% Z( P6 X1 c) b
1、声明式事务管理: 1.流程:由客户端访问—-aop监控—-调用advice来追加事务 2.做法: 2.1 在配置文件的头中引入xmlns:tx 和schema的文件 2.2 2.3 注入数据源
, u1 o3 i0 l/ W% f3 N; [, g# V3 g+ B! ^
5 W. _: a- {- i2 j1 R
2 t& K- b @3 L
1 r/ M8 o& i! r% H$ U8 s( z9 j: w5 Q# {* p* s8 N3 b! b$ X
2.4 由spring实现的事务管理,但需要注入数据源
9 Y. c8 v! c! m! R4 ~6 z2 z6 ]$ m2 w, h3 U
2 c+ g$ W1 F+ S: C2.5 事务监控所有的方法(事务加强)
' \) r( o* g5 t- {9 V4 V2 o/ d2 {
/ N4 } E5 N' M/ m1 u E) C/ X) V7 b
: [1 Z X& j9 B, n, B# N( D$ }6 q1 M5 _9 s; T
2.6 定义切入点
, a+ c' E4 l1 q
h0 I4 S2 o S
2 G }1 j4 o" N% |& n7 ?" G5 b- q$ U$ R6 e+ f
' C, ]0 _ k$ l3 K' \ a, {3 G0 m1 x; {2、使用注解实现事务管理: 1.注解@Transcational (可以在类上,也可以在方法上) 2.在配置文件中同样需要注入dataSource和spring的事务管理 3.使用注解的方法来追加事务 注解驱动 9 I! T; e! n9 l5 H( G
) v* {. m, m9 y% B' Y如何在Spring中使用Hibernate的事务:
* v; r% @) d( \% ] b6 k 7 r' L, K; ~2 i
9 S2 [4 W' e& @6 T
0 _0 E: V& l+ [4 d如何在Spring中使用JTA的事务:
: O. J/ x( J5 |% e* X9 s
$ n, k% G7 M! ]3 k. F: C2 d |