Spring6 ]# b( [, ]# \
- 是什么?
: s, ]! m( o9 N+ q3 f' c( N4 m0 q" H: z9 B9 B
Spring是基于JEE的轻量级的应用框架
: S' G- g0 M) ], b+ v. J. X$ G- 有什么?
: `( n/ F2 l2 h/ Z7 g
2 g$ M2 A0 t8 I; [- |2 k , _# e: X' j# `+ P ?' @; t1 ^; ?
每个包的功能: Spring MVC:spring 本身提供的web 框架 WEB:集成其他的web 应用的框架,或者说是对其他web应用框架的支持。如struts,webwork JEE :集成一系列的jee的技术(对JEE技术的支持) DAO:封装了JDBC;(对JDBC的支持) ORM:提供了对ORM工具的集成(支持) AOP :面向切面编成 CORE:spring的核心包,提供bean的工厂和IOC容器
. @; p, P8 J3 Z/ J5 o% d p0 Q- 能干什么?2 g* G1 u+ j$ `- x6 B
- y5 O3 k) z$ v9 z
把一系列的jee的技术有效的组合在一起形成以良好的系统 5 m' y! o1 N, b6 Z
- 怎么用?
! I. K! F5 p# X# `
. b# E$ ~ P7 d& q- g% b- 搭建web工程,引入spring的jar包# p4 e$ `" `4 c9 F
- 在web.xml中添加如下配置) t4 F7 v6 ~7 C! C/ a) T5 ]& c( p
; o1 `6 L$ F$ @% L, ~1 L- @& S
4 D8 [9 O6 z& j% S$ F# r2 d0 @% V2 H8 r
; }2 v" R: T, @
contextConfigLocation3 W6 ^& u/ j' W4 H1 F) j
classpath*:applicationContext*.xml
+ R/ r' X L5 O6 |
, ^5 a# @) ^/ z$ D% O " L U* G. g C% Q
struts20 W+ [: W3 K. D
7 g1 l$ N1 A! s' a
org.apache.struts2.dispatcher.FilterDispatcher* r7 Q' s+ J! S4 \( X @9 V$ p
0 v+ I- q* S' E# |" \ + P: ^1 r0 y. a6 t9 v: C+ p* U) g
2 }2 k1 Q% o* F( V0 _+ Y9 ~! d4 ]
struts2
( f2 M# u2 u, q /*
) S/ z- k1 `2 R7 C& s# x
* p0 G% O6 B! v9 |
- G, b0 s2 W6 Q0 Z/ o
7 Q/ l2 D+ Z8 C, N+ b9 k
org.springframework.web.context.ContextLoaderListener
" i4 V7 { G8 Y- y9 u _0 K
& X0 B% D2 d4 S6 u, c( A - 部署
& B2 M) Q9 v/ |, ^7 z! x7 X5 }% f! ]& S; E# O
6 U! q( b$ \9 z. J& d& ?' v- t0 P) |
. _3 W6 P& h9 s% A o
7 q! x, `4 X. ~7 J7 i
- 容器和bean( i$ [6 D; k: i& J
Bean :是指受spring的ioc管理的对象称为bean 容器 :(与jee的容器类比) Jee :提供组件的运行环境和管理组件的生命周期(不能单独存在) Spring :提供bean的运行环境和管理bean的生命周期(可以单独存在) 4 R: X% Q4 I( K7 J
6 @$ ?) ^( a* L) c$ _
- DI依赖注入& d. v* _0 c3 t" _% b- `. d
1. 应用程序依赖spring注入所需要的对象 IOC和DI是对同一种事情的不同描述 2.setter注入: 在配置文件中将接口的实现配置为bean在应用程序中注入bean 例如: 在配置文件中 : A& I0 v& V# C0 a) c, @7 G
7 e) z% G3 G. o
) y: w( s: d8 q$ E, s2 s在应用程序中 Public DBDAO dao ; Public void setDao(DBDAO dao){ This.dao = dao; } 3.构造器注入
2 P: R. G4 G& ~( f# ~. B# ^- q/ U4.ref 表示参照其它的bean 在参照的过程中一定要注意死循环 5.自动装配———–〉no 自动装配根据名字来匹配相应的bean 尽量不要去自动装配 6.lookup注入 7.singleton 1.单例模式是整个的jvm中只有一个实例 2.spring的singleton是指在spring的容器中只有一个实例 一个生命周期中只有一个实例 8.DI的优点: 1.程序被动等待,强化面向接口编成 2.切断了对象或组件之间的联系,使程序的结构更加松散,运行和维护更加简单
9 ^- O7 P0 y7 R {- Aop面向切面编程" B0 g0 g- _0 o" Z' U0 K5 ~+ D
! y" E! Q z! b( y' @
1.AOP面向切面编程 一些较好的模式或者是示例—-范式
# n% O0 n- o0 {4 W7 I# D 切面:一个切面代表我们所关注的一系列的共同的功能点(模块之间的共同的功能点) 2.AOP的思想: 主动—->被动(追加功能)
/ C# T% x; ]7 C2 I3 e- P M 3.AOP 的概念, |0 x# l8 D5 H+ |
1.切面 :我们所关注的功能点 2.连接点 :事件的触发点(方法的执行) 3.通知 :连接点触发时执行的动作(方法) 4.切入点 :一系列的连接点的集合 (连接点的模块化) 5.引入 :扩展的功能 6.目标对象 :包含连接点的对象 7.aop代理 :实现机制 8.织入 :把advice和目标对象连接起来 4.AOP的事件机制
" \' s/ U# g/ ?# g9 Q# f7 d# U9 F X 1.通过切面找出一系列共同的功能点 2.找到目标对象(在标准的spring 中 接口的实现类为target) 3.找到切入点 4.确定连接点 5.通知spring AOP,查询xml文件,通过代理找到advice。 6.由aop代理来实现动态织入 2 z+ }" C& h1 Q. Q7 \1 I6 f# q" t
- X4 R. q! @) f/ x3 J/ r/ f
( h* F- v5 X4 \& N U2 y0 F* Y+ v$ X8 z8 Q6 @; H% L- X
+ A# o7 a1 M0 F3 Q3 V5 U/ O6 j
: d8 a9 i) A7 ?* ~. y8 W p$ B- _$ P9 Y, ~9 W# j: D# C) P6 `" X
5. AspectJ$ t3 U! l$ n' u* k6 }; Q
5.1.在xml中配置比较烦琐
( Q2 ^0 ^; T. h8 [9 _, ? 所有的入口必须从一个代理(ProxyFactoryBean)开始
+ d- U% K% O, D$ t/ S ; w1 y: J- u. v8 Q% \
+ o8 S& x' g" ~3 W6 H, m2 J4 @* n" b
+ j& j# W5 `! m6 u1 X6 r1 w' h1 C2 H! o& L
_! L) B+ L! G0 {
1 p5 {6 Q! Z$ L/ O+ V
8 C$ p7 u% o) u! P/ R. M
; ^8 a h4 N/ A: z% ^1 \5 V W" I# ~expression=“execution(* com.javakc.aop.MyTarget.t*())”/>
! x# ^9 `) ^ y& r X+ I$ G1 q
8 o) a. ]+ n: `/ @" H# @/ U 7 ?7 C7 D' N8 O8 @. ]# M2 U9 s
) l& ~, `7 X! |8 b
{0 Q/ `" R/ A3 M5 p
3 U& l5 W( g) }# x5.3.使用注解的方法相对简单4 R' P; T/ k, f$ I' K% ?$ o: S
@AspectJ的基本语法
# s0 W- J$ g! t 1.@Aspect声明一个切面,将一系列的共同的功能定义成一个切面
5 i3 ]0 [& N0 {, u: p4 F6 x1 P/ p: H 直接在类上定义@Aspect
3 K! O0 i8 K; z 2.@Pointcut声明切入点6 t4 K5 v3 q/ n! q0 i4 j
2.1、用一个专门的类来定义pointcut,类中的方法名就是该pointcut的名字: w" X) y Y2 j* L# S' D+ r0 r
2.2、可以使用匿名的pointcut
6 p0 a' ^# W) v6 i s, N9 G5 O& ? 2.3、执行切点的几种方法6 E) g. p! ~" k+ A' c
2.3.1 execute(public * 包结构.*.*.(..)) 可以指定到具体的方法
& ~: Q. ^( H) ^5 P 2.3.2 within 指定到包,不能指定到类' f8 y: a5 g! b9 j/ H' S1 D
within(”com.javakc.spring..*”)- G M5 E3 t- H- r! S; }* o
2.3.3 this 指定到实现接口的所有的实现类
( w8 ?8 a8 o9 U9 p+ D! m. S 2.3.4 target 指定具体的实现类5 `3 |1 N! Q, s! i* \
5.4.advice的五种类型的示例8 \5 y P- l2 U' w% i' v
客户端必须从接口走才能得到监控,实现想要追加的功能; n$ R1 o1 D7 R: v' C- N
5.4.1.@AfterReturning(pointcut=”” returning=”retVal”): L! a9 O" g1 `; @" t4 v
追加的方法的参数名字一定要与retrning的名字相同; U2 B$ w$ x- {( z" X5 U; T% z& ~% `
在注解@AfterReturning中必须加上pointcut和returning两个参数% r4 U; v3 { D3 s
pointcut指所要监控的目标对象的方法# e" i5 x# }4 Q G& u; E& o
得到目标对象的方法的返回值,来作为参数,进行下一步的处理,参数没有顺序,按参数的名字进行匹配; z- q" b! H! B/ ?- W" i
完成追加的功能& p# ^- P* I" r
1 定义一个pointcut,通过方法名来作为pointcut的名称来引用4 V6 O7 H8 Q$ m4 B2 F; B
(1).@AfterReturning(“com.javakc.spring.schemaaop.TestPointcut.t4()”)
$ l7 C* L8 r$ k; J% X4 ]4 u (2).
5 m/ L; X {9 n+ j0 T+ h+ Z$ M 2.直接引用匿名的pointcut8 b) G& ~+ s8 F- M \7 R8 k, w
(1).@AfterReturning(“execution(
% x# A1 W q6 k1 S- {2 H! c * com.javakc.spring.schemaaop.Api.test4())”)
/ ]! z% ~. o$ u$ O' `& @9 b (2).@AfterReturning(pointcut=0 x. Y0 B6 G6 R4 O! \! c2 y. [
“com.javakc.spring.schemaaop.TestPointcut.t4() &&! A9 ?3 I. F k8 }/ z6 ?% m
args(str)”, returning=”retVal”)
: f1 d. y; n: v0 w) I8 H @AfterReturning (pointcut=”com.javakc.spring.schemaaop.TestPointcut.t4() && args(str)”,returning=”retVal”): J+ x6 }( n8 i0 c9 J! g5 q5 g
public void testAfterReturning(String str,Object retVal){
, }0 z. M+ l- O8 A/ Y' {3 C System.out.println(“afterReturning1=>”+retVal+”=>”+str);/ R4 R; @3 M: W' G$ v! y: H
}
1 ], ] a/ G7 A _ 5.4.2.@Aronud( S, X, p5 [) y; R) L4 M3 \6 h% O
注解@Around环绕追加功能;* a# v; [1 Z7 K+ l. H2 d
在执行目标对象的方法的前、后追加功能;% U+ j$ ], t. R
必须有参数;第一个参数的类型必须为ProceedingJoinPoint;% D0 f5 X! |2 _4 q" y
通过ProceedingJoinPoint的实例的proceed来调用所监控的1 x+ ~6 f4 O2 s& p& B6 x3 W- z
目标对象的方法0 x; K" R7 @6 c# ]
1 定义一个pointcut,通过方法名来作为pointcut的名称来引用5 T0 \( N5 T$ I
(1).@Around(“com.javakc.spring.schemaaop.TestPointcut.t1()”)
! L4 j2 G: M( m V$ O5 R! N I (2).@Around(“com.javakc.spring.schemaaop.TestPointcut.t2()' X6 B0 t# l% u6 `% G' S0 k/ D
&& args(str)”)
! w% `; `1 Y1 H 2.直接引用匿名的pointcut
5 o. r- \: W" b" { P (1).@Around(“execution(% z! x2 m" u- V5 X
* com.javakc.spring.schemaaop.Api.test1())”)( I+ t2 [$ D2 Z
(2).@Around(“execution(
' B4 a8 w! a9 q) e/ H* M2 M * com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)! \0 ]5 q2 C, ?1 A# r. D! V; Q6 S
// @Around(“com.javakc.spring.schemaaop.TestPointcut.t2() && args(str)”)
8 L1 r; |5 M* Y( S; h8 G. m @Around(“execution(* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)
, [2 o- q6 ]% k9 ?$ J) T public void testAround(ProceedingJoinPoint prj,String str) throws Throwable{- N% w1 c' N* x0 s
System.out.println(“around1==========before1pointcut==>”+str)
# A8 Z3 |8 ~) l( Q Object obj = prj.proceed();
! c# U. k" I1 x" ^; j* \* G8 K System.out.println(“around1==========after1pointcut==>”+str);" L9 i$ ~6 U! L; ]1 o" ]% P
} \6 l. @, }& J$ `* z4 a% N
5.4.3.@Before8 R8 b2 G' q$ [% j0 k
注解@Before在执行目标对象的方法前追加相应的功能
q+ ?* \7 b$ ? 1 定义一个pointcut,通过方法名来作为pointcut的名称来引用
g: P- V6 l, `2 v( d6 G (1).@Before(“com.javakc.spring.schemaaop.TestPointcut.t1()”)+ c( R2 c& F; M3 b! @2 Y& b
(2).@Before(“com.javakc.spring.schemaaop.TestPointcut.t2() && args(str)”)
/ X: Q6 |( w I 注意args后的名称与参数名相同
0 T+ v6 T" @. k 2.直接引用匿名的pointcut
; }$ b: Y" w2 M' j* q- Z( i (1).@Before(“execution(* com.javakc.spring.schemaaop.Api.test1())”)" y2 l3 S9 O# t; t( n: D( u5 O
(2).@Before(“execution(* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)& Q/ ^ {3 F. y/ h( W, @- K
注意args后的名称与参数名相同. G3 ]( Z6 N" W2 ~) C
// @Before(“com.javakc.spring.schemaaop.TestPointcut.t2() && args(str)”)$ U% M6 \2 u C! g" ^3 ~5 J! ]
@Before(“execution(* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)
' \: S! F) K3 }4 H8 [; J. D public void testBeforeParam(String str){
! L, t4 G: q& c$ X System.out.println(“before1=param=>”+str);
" a/ O5 X$ A6 a$ Z3 o0 {- `- c }
; y0 r1 r$ s! S! d7 v2 Q
. p5 k4 u$ l1 {5.4.4.@After: ?& \& J9 U0 \+ i; Y
注解@After在执行目标对象的方法后追加相应的功能) u0 f. U: S* F* `
1 定义一个pointcut,通过方法名来作为pointcut的名称来引用2 u: u: M& T; R J
(1).@After(“com.javakc.spring.schemaaop.TestPointcut.t1()”)
: E; u. n" \/ a1 A+ p N 2.直接引用匿名的pointcut4 L: Z* F. n5 L8 S% l) R
(1).@After(“execution(* com.javakc.spring.schemaaop.Api.test1())”)8 @' m4 J( |# T6 u* J' K1 T7 [8 Y
@After(“com.javakc.spring.schemaaop.TestPointcut.t1()”)
D) g9 E& s: w public void testAfter(){
. @6 z4 X& M& t System.out.println(“after1== >pointcut”);9 m0 ?- x6 j9 j
}( P8 I' Q0 A3 ]: P
5.4.5.@AfterThorwing! G5 l/ {1 {; V# x, D% w
+ v O {8 [( X! D; Q" X' i
# I% B& O" z7 Q; t% ~
- 描述一下spring中BeanFactory和ApplicationContext的差别1 u1 P; s2 J+ C r, S3 Z n
$ g. E- Y- d3 x+ P4 t
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”); ! V. ^2 X; _" O' G
- 谈谈spring对DAO的支持
4 J' n( I7 A" L# e; D: v; k3 a' d' I0 g
Spring提供的DAO(数据访问对象)支持主要的目的是便于以标准的方式使用不同的数据访问技术。1 C5 d, P0 {) Z- G1 M
简化 DAO 组件的开发。
3 S# A1 m- f& u; |0 ^$ ?7 R7 ASpring提供了一套抽象DAO类供你扩展。这些抽象类提供了一些方法,用来简化代码开发。
9 G" j! z/ L& E, p IoC 容器的使用,提供了 DAO 组件与业务逻辑组件之间的解耦。所有的 DAO 组件,都由容器负责注入到业务逻辑组件中,其业务组件无须关心 DAO 组件的实现。
0 @' }+ ~5 N: A1 C+ V 面向接口编程及 DAO 模式的使用,提高了系统组件之间的解耦,降低了系统重构的成本。4 a+ l4 R1 q3 f0 M- Q# T( q- s# O
方便的事务管理: Spring的声明式事务管理力度是方法级。5 I' n2 U" o% V( ]; U
异常包装:Spring能够包装Hibernate异常,把它们从CheckedException变为RuntimeException; 开发者可选择在恰当的层处理数据中不可恢复的异常,从而避免烦琐的 catch/throw 及异常声明。
+ c: p$ P( j* l. L {9 B* F 5 G% K: k* L1 O% c
. [" w& t) B! j' v q% d5 ]- 谈谈spring对hibernate的支持# P* D5 ~7 G$ q4 I
3 I( U- {) G- ]
在所有的 ORM 框架中, Sping 对 Hibernate 的支持最好。如 SessionFactory 的注入、HibernateTemplate 的简化操作及 DAO 支持等。另外, Spring 还提供了统一的异常体系及声明式事务管理等。- f! N; ?; j- m! R/ l/ m; l
一旦 Hibernate 处于 Spring 的管理下, Hibernate 所需要的基础资源,都由 Spring 提供注入。Hibernate 创建 SessionFactory 必需的 DataSource ,执行持久化必需的 Session 及持久层访问必需的事务控制等,这些原本必须通过代码控制的逻辑,都将由Spring 接管ataSource, SessionFactory, TransactionManager等,都将作为 Spring 容器中的 bean。将这些bean 放在配置文件中管理。
0 L! S' a+ s e 1、通用的资源管理: Spring 的 ApplicationContext 能管理 SessionFactory,使得配置值很容易被管理和修改,无须使用Hibernate 的配置文件。详细配置如下:
) ~. E6 e" E: ]' | * g' W4 Y7 s* @3 j. ]0 c; E
class=“org.apache.commons.dbcp.BasicDataSource”>
3 {* [. \2 o3 |0 D 7 B) y% N( s/ w# N d7 E4 o, y
oracle.jdbc.driver.OracleDriver V- u Y5 ~/ e% W- B
" t) ]( d6 r$ z7 W
: N( u; a$ B& C1 x* j Q jdbcracle:thinlocalhost:1521rcl# O# M/ q+ [4 C
$ l% N, u6 f$ U4 \2 X8 {7 Z8 N( z. h * V# y; i" O" s6 B
javakc2 V& q2 O4 }9 O
+ `8 U6 E5 Y9 {2 l5 ] , F w5 H' T9 v! Y! Y, c9 n
javakc2( g- _8 a$ f# F1 n
8 \# @' V, I3 _6 W( f+ \
5 U9 t. c# Y4 g/ O2 O , Q( C5 [2 A( o6 @
class=“org.springframework.orm.hibernate3.LocalSessionFactoryBean”>* u$ M, b1 q: _
% r0 V+ Z) S0 ?* ~" x- C4 A( y* ?
. V/ x: E& G3 R u2 K# O! g
- X. H8 B% W) S, o5 ~" v, p com/javakc/spring/h3/UserModel.hbm.xml
- ^$ V q6 J/ C2 T, e Y2 e- U, h! R9 ~
! S q7 ]9 |9 h1 y+ {
N. t5 M! s E) L/ x
& A" a- R( M* a7 k2 i: G hibernate.dialect=org.hibernate.dialect.OracleDialect6 H% }% Z8 o- x) `/ ?! Y
4 ~5 L. i& `5 r- \4 R4 }
2 i. G7 ~# W1 M' }$ p3 \/ P
" J. ]$ ^, d' T i* ~5 v
) Y2 b8 r. s6 Y/ }1 Q' ^3 b
5 |: o' j( O4 i% K, M8 J 6 t. R6 K y" }, o
如果需要使用容器管理的数据源,则无须提供数据驱动等信息,只需要提供数据源的JNDI 即可。对上文的SessionFactory只需将dataSource的配置替换成 JNDI 数据源,并将原有的 myDataSource Bean 替换成如下所示: class=“org.springframework.jndi.JndiObjectFactoryBean”>
0 J+ i! o. Y: y% y a! e, i ( {: A2 a1 B' P6 ^
java:comp/env/jdbc/myds
3 {5 f3 r# \6 m$ X 4 h" t! Y `) e. B3 O' N
2、有效的 Session 管理: Dao类继承HibernateDaoSurport后,Spring 提供了 HibernateTemplate,用于持久层访问,该模板类无须显示打开 Session及关闭 Session。它只要获得 SessionFactory 的引用,将可以智能打开 Session,并在持久化访问结束后关闭 Session ,程序开发只需完成持久层逻辑,通用的操作则由HibernateTemplate 完成。 3、统一的事务管理。无论是编程式事务,还是声明式事务, Spring 都提供一致的编程模型,无须烦琐的开始事务、显式提交及回滚。 建议使用声明式事务管理,Spring 的声明式事务以 Spring 的 AOP 为基础。可将事务管理逻辑与代码分离。代码中无须实现任何事务逻辑,程序开发者可以更专注于业务逻辑的实现。声明式事务不与任何事务策略藕合,采用声明式事务可以方便地在全局事务和局部事务之间切换。 Spring声明性事务有两种配置方法,一种是xml配置: ) V7 V, j; d h4 x' z0 P8 D$ O
! j3 t/ R7 `2 z- P P9 \
$ D, {7 g0 o: K% d% i
. i5 L }: R% m G8 A ^% @ V 1 z6 c8 Z! B D# s; d _( B
, I$ K0 [7 e; s# p: Z! f 1 ~$ I+ ^7 {9 h; A+ @* U, K
5 \2 X3 x; K- `- l3 V % H! k2 r5 s2 S/ K' H. M+ h4 q0 Q
! V8 T+ [# `/ U9 O2 z7 L- s 7 y# ~; M: n8 O6 c& G' H8 Y
8 `/ \$ p2 Q: A, |* ]3 x
G+ y( p8 @8 p% P* ?5 R
% r2 @# Z% m; o 另一种是通过注解,在需要添加事务的类上注明 @Transactional ; q& s0 d) ~3 b/ ?2 M
Spring2.0之前事务的写法
1 b: _* y* c! I4 A) F
7 n, H+ w3 E }3 a
* e% A, E; Y9 B0 ~8 b8 g8 I1 h class=”org.springframework.transaction.interceptor.TransactionProxyFactoryBean”0 T" U6 q4 ?4 `3 \/ r* d0 U
3 f8 _# v+ ^4 N! ^
abstract=”true”>' ]: q- Z: j6 ? C6 f
6 a' F: Q; B; [0 C! H0 |" S. _& ]7 D% Z5 T$ q# l; K
~" p- Z5 J& o' r, x9 [4 T
0 _2 k) H: A: ?' ? PROPAGATION_REQUIRED,readOnly3 D' m: p0 c$ d& v7 q
$ T0 r F4 v+ B
PROPAGATION_REQUIRED
3 O4 ?4 g$ z: L; M! G# L* Q
R1 q( o; `0 A7 ?: R+ V Y3 W4 ]
! t2 l0 Q" m; f. w! t1 Q9 q/ Q
% I* X' B! J, [
3 W* z' v+ I7 ?8 `1 P% P* g3 j% ?$ o |
5 y, M1 R1 f) ^) j/ i
, \3 p' P# F4 }/ E1 q: L2 L- 谈谈Spring对事务的支持
* [9 x2 G; X4 h/ o$ A
: a0 Y1 q9 d( G# w
1 W; [7 q% `; b: K( G
1、声明式事务管理: 1.流程:由客户端访问—-aop监控—-调用advice来追加事务 2.做法: 2.1 在配置文件的头中引入xmlns:tx 和schema的文件 2.2 2.3 注入数据源 ; O6 }& @( S/ O. x
4 l, o: F9 X$ W2 _2 Z
. {9 r% `1 v4 P4 h4 ~* l
, E, X, @1 I: L* z3 H; o
. e) l) e% ^& E+ A+ H. n a, W
* x r6 b5 P, i1 H9 N; w8 {2.4 由spring实现的事务管理,但需要注入数据源
; Z0 p7 \3 J! G! x- ?' Q. o. ?2 D. D' ?7 _% N( ]2 I) T
. H8 B/ {- F J* w
2.5 事务监控所有的方法(事务加强) 8 f% \4 R& W' Q* z9 `3 ]
3 L" V; W' ], i1 _, k+ h( |# |3 |, I6 p+ a
- V1 }% B _& U1 B9 [# f
) f. x9 ^. X/ v# f5 h1 B! ?; L+ E1 Y2.6 定义切入点 : R+ U' Z" n# L8 G) ?2 ]
, s( P. A. ]- m: s# j
# P8 h$ f' C1 h: o
; E) b! ]) d& Y2 Y9 A$ `
% ^# i9 u! o/ ~5 K2 D: l: K9 ^# c. ^2、使用注解实现事务管理: 1.注解@Transcational (可以在类上,也可以在方法上) 2.在配置文件中同样需要注入dataSource和spring的事务管理 3.使用注解的方法来追加事务 注解驱动 7 ^5 H- x& i! q: x. @( j
! t, {% B9 H5 s% z7 G, A
如何在Spring中使用Hibernate的事务:
9 k. {, X" l+ j. t: |+ b
4 {5 S7 f5 a k7 W( n8 L3 u
$ S& }9 Z: q6 B: i( C
* d( B b; Q M. d. C, }+ T如何在Spring中使用JTA的事务:, I0 S- A1 c, ~, i0 O
& Z7 Z z* C* m$ d+ Y, a# D: {
|