Spring7 g$ J) j$ D2 d$ H4 p
- 是什么?
( `0 E q; l# k; G1 M0 q1 ^- ]
$ f* \( I- q. D o* U, Z7 h
Spring是基于JEE的轻量级的应用框架
7 a2 f8 }) @) b; d7 I8 x- 有什么?
1 c& Y# E! N, v! b9 |$ I. J% U; l( [/ ~9 ~6 R) r6 u3 ^& c
1 [8 {9 j' J$ e& ]6 j5 ]
每个包的功能: Spring MVC:spring 本身提供的web 框架 WEB:集成其他的web 应用的框架,或者说是对其他web应用框架的支持。如struts,webwork JEE :集成一系列的jee的技术(对JEE技术的支持) DAO:封装了JDBC;(对JDBC的支持) ORM:提供了对ORM工具的集成(支持) AOP :面向切面编成 CORE:spring的核心包,提供bean的工厂和IOC容器 ! ~: C5 B! Z$ G ^) Y @0 L: k8 d
- 能干什么?" L5 z, }. l7 }5 o# u8 U t
9 L( m! I) W2 W" _8 @$ W" i4 u
把一系列的jee的技术有效的组合在一起形成以良好的系统
5 p+ n% p y+ R* l; p- 怎么用?) O7 [! v: |2 ~ A9 ^* m: j" i0 ?
) J4 Q' E& P* C2 @- 搭建web工程,引入spring的jar包: o; C; ^) s0 a; z
- 在web.xml中添加如下配置8 a: |! D0 D( b3 I
8 D. D: `" ~ D P1 b N+ R; V
- D. ?' y! Q: ~5 {8 `' q5 U; U+ d/ p
contextConfigLocation
; r" M1 N$ ~/ q) z$ a( v classpath*:applicationContext*.xml# P+ O( l/ F% S0 q" d
. L: \) j1 n+ _7 c* E' B% U" X5 i $ Z( _7 k8 F- r; E+ D+ }9 Y
struts2
8 p, b, i) B* k' e7 A+ Q4 l6 S+ _, k
3 M- E3 C( n4 u& G org.apache.struts2.dispatcher.FilterDispatcher
, H6 Y' O5 d1 e% N, g- ]
. G7 b" b' S# M# ]$ [
# v- K6 R& [' W7 @" o7 L
7 } n8 [: l {1 S+ S struts2
9 O7 U6 L7 s# a4 j3 R /*: B" Y4 A+ T. E2 X2 ]
9 a1 p% k" A7 a: f$ L% b
( {5 C) y7 R( G
6 z- P4 E* S2 v
org.springframework.web.context.ContextLoaderListener! e9 {8 }6 Y" A' `* c" }) s& H! Y
! w- {4 r2 q! i2 I
- 部署* H" J. \0 i4 @7 b
' S! U% U3 T/ O. n: H1 w * W' }- y/ o0 b
) a' s2 t& n# U, e. @8 T
3 Z( b8 g5 }5 B' ^' W0 \8 A
Bean :是指受spring的ioc管理的对象称为bean 容器 :(与jee的容器类比) Jee :提供组件的运行环境和管理组件的生命周期(不能单独存在) Spring :提供bean的运行环境和管理bean的生命周期(可以单独存在)
0 |7 b7 P: ^ U/ ~+ j5 |* F+ B3 c: f6 L$ N2 O- c" m2 x
- DI依赖注入+ [7 y, t7 O& k( F6 v
1. 应用程序依赖spring注入所需要的对象 IOC和DI是对同一种事情的不同描述 2.setter注入: 在配置文件中将接口的实现配置为bean在应用程序中注入bean 例如: 在配置文件中 ~6 E4 c. R: R) B9 s4 y* K
3 _+ F" `! r( [( H5 D
/ U; m; r7 `0 e在应用程序中 Public DBDAO dao ; Public void setDao(DBDAO dao){ This.dao = dao; } 3.构造器注入
- }2 B! L6 S( {: q6 w6 Y5 y% T4.ref 表示参照其它的bean 在参照的过程中一定要注意死循环 5.自动装配———–〉no 自动装配根据名字来匹配相应的bean 尽量不要去自动装配 6.lookup注入 7.singleton 1.单例模式是整个的jvm中只有一个实例 2.spring的singleton是指在spring的容器中只有一个实例 一个生命周期中只有一个实例 8.DI的优点: 1.程序被动等待,强化面向接口编成 2.切断了对象或组件之间的联系,使程序的结构更加松散,运行和维护更加简单
, M' E0 V+ F, T- Aop面向切面编程
) s, c% l0 C) D3 n# f
* D9 L2 f4 ^2 d. X
1.AOP面向切面编程 一些较好的模式或者是示例—-范式8 C2 c7 W( f4 V; n$ H" I- b e
切面:一个切面代表我们所关注的一系列的共同的功能点(模块之间的共同的功能点) 2.AOP的思想: 主动—->被动(追加功能)8 o- e5 x# x) Z9 x H' g0 Q
3.AOP 的概念
+ U8 J# V9 t; ~0 l3 N 1.切面 :我们所关注的功能点 2.连接点 :事件的触发点(方法的执行) 3.通知 :连接点触发时执行的动作(方法) 4.切入点 :一系列的连接点的集合 (连接点的模块化) 5.引入 :扩展的功能 6.目标对象 :包含连接点的对象 7.aop代理 :实现机制 8.织入 :把advice和目标对象连接起来 4.AOP的事件机制
4 B0 l3 I3 J2 A) A% t. J5 l- I! z 1.通过切面找出一系列共同的功能点 2.找到目标对象(在标准的spring 中 接口的实现类为target) 3.找到切入点 4.确定连接点 5.通知spring AOP,查询xml文件,通过代理找到advice。 6.由aop代理来实现动态织入
7 c: ^2 ]2 ] J% T( ]5 e/ W2 P! K5 p! \+ ^" O! L5 _
' R/ @. z& p" x- e9 n" g+ M9 \ L* b y! w- }
) Q4 Y$ X6 c/ f& U. H6 @3 U
6 K3 D! S' L; K: \
5 I$ ~+ {6 q: l! H: d8 Q2 ~5. AspectJ- g( ^+ q. ]+ P% o
5.1.在xml中配置比较烦琐
/ V. A+ l4 m$ P: ? l' J 所有的入口必须从一个代理(ProxyFactoryBean)开始
8 K) N' w, |: W6 i4 m1 A
1 ?6 y( F6 s. E% o( _5 ^& a% m + d3 z& u. \* u
# l2 K9 `, F! h& X$ i: R! P
* D/ |& g# T A. L5 P# u
. F( V$ p3 O" T- m; r3 m % |1 c" [ E5 A3 ~& s5 O
& @8 K6 Q' B/ r
/ e- F j; h! A% {/ z# Fexpression=“execution(* com.javakc.aop.MyTarget.t*())”/>
* c" f! x* ~: t" k( P
) B0 b# X9 |# A, A0 u0 g
# n, m1 h# b7 k- M
; [. M4 F; @4 Y9 ]2 j4 J4 e
" O$ [# ^; O8 s& C! [( d2 J6 f3 C' W0 z8 O- a. S" E1 |4 w
5.3.使用注解的方法相对简单
. E G# s9 S: G @AspectJ的基本语法
& m) U: [& e2 V- O, F! { 1.@Aspect声明一个切面,将一系列的共同的功能定义成一个切面: d( p, S# \! v) f: K
直接在类上定义@Aspect8 t+ n4 ?& i# D% Y" j
2.@Pointcut声明切入点
2 }" }4 B/ C* \4 l' c3 b 2.1、用一个专门的类来定义pointcut,类中的方法名就是该pointcut的名字8 F7 ]" S$ U4 p) M7 K( X1 x8 _6 R
2.2、可以使用匿名的pointcut: c! q5 V0 i7 n7 j5 @9 p
2.3、执行切点的几种方法1 w# w v4 G1 f v) r+ T- o/ C% P- |
2.3.1 execute(public * 包结构.*.*.(..)) 可以指定到具体的方法
+ J: w! s4 }6 {' G 2.3.2 within 指定到包,不能指定到类. k F7 A" V- R/ U! l0 ]7 Y! H% q C
within(”com.javakc.spring..*”)
1 P% V/ m5 V* ?) S 2.3.3 this 指定到实现接口的所有的实现类
! B' L6 ^: |7 K. s% y) ]$ _ 2.3.4 target 指定具体的实现类
7 s5 y; [; O) K6 H3 s% I1 C0 h. Y 5.4.advice的五种类型的示例
' C& m# Z( h( b9 I+ N( i 客户端必须从接口走才能得到监控,实现想要追加的功能& v: T0 H9 M. u. p6 A
5.4.1.@AfterReturning(pointcut=”” returning=”retVal”)
5 z8 h; S0 ?6 `2 y' g# {. H9 w 追加的方法的参数名字一定要与retrning的名字相同
9 Y$ x. |1 e# g, y) K2 _ 在注解@AfterReturning中必须加上pointcut和returning两个参数" P' K3 Z8 L, S' u1 P0 c9 r
pointcut指所要监控的目标对象的方法
) K* ?* e+ {" \6 Q. L' t {7 T 得到目标对象的方法的返回值,来作为参数,进行下一步的处理,参数没有顺序,按参数的名字进行匹配* i J" K' S+ \" `$ j9 h
完成追加的功能 |) ~( z7 G- w3 R, Q
1 定义一个pointcut,通过方法名来作为pointcut的名称来引用
- {: L$ h) l+ l0 K% _8 F! S5 } (1).@AfterReturning(“com.javakc.spring.schemaaop.TestPointcut.t4()”)' ^: G: j3 z, c5 ]- n3 S
(2).: N/ d6 q) i. h! l9 N
2.直接引用匿名的pointcut
& p# n) z/ i0 Z S- U0 T (1).@AfterReturning(“execution(
4 m- u! y5 s. d" i- O * com.javakc.spring.schemaaop.Api.test4())”)
" P" R9 ^1 ?# P5 O Q1 a, L0 W (2).@AfterReturning(pointcut=: z2 N8 N& |" ^8 b! [' J
“com.javakc.spring.schemaaop.TestPointcut.t4() &&
9 d. t% Q( A Q! j! f2 C: E: N args(str)”, returning=”retVal”)
+ _- ]) \0 ?# N4 [0 k$ e! l @AfterReturning (pointcut=”com.javakc.spring.schemaaop.TestPointcut.t4() && args(str)”,returning=”retVal”)8 ~/ J$ s7 C& o$ g/ Q5 Y$ ?. D
public void testAfterReturning(String str,Object retVal){2 \; t8 f3 N( V
System.out.println(“afterReturning1=>”+retVal+”=>”+str);) f+ @7 p( h9 _2 Z6 V/ B' `7 t
}, F) X, [$ l4 d& _
5.4.2.@Aronud
/ n' f3 W) _3 v! q5 t 注解@Around环绕追加功能;6 X" |* g* W* y$ z
在执行目标对象的方法的前、后追加功能;
+ T- x" M4 i/ i% f4 f8 ]5 z6 d 必须有参数;第一个参数的类型必须为ProceedingJoinPoint;
: @* Q' i U+ |. } 通过ProceedingJoinPoint的实例的proceed来调用所监控的
; J; \) j0 ^; H6 b$ { 目标对象的方法7 U' Q( G) {; F
1 定义一个pointcut,通过方法名来作为pointcut的名称来引用
# B' @5 c2 z# M4 h (1).@Around(“com.javakc.spring.schemaaop.TestPointcut.t1()”)
( j3 v2 {$ {+ t (2).@Around(“com.javakc.spring.schemaaop.TestPointcut.t2()
' F& P& M, s G8 C && args(str)”)/ D; v4 P% \, y( ~9 n
2.直接引用匿名的pointcut. w1 A# r) a/ n" T
(1).@Around(“execution(
4 a) W7 _3 r( {* x$ P2 U * com.javakc.spring.schemaaop.Api.test1())”)
( ^5 Z, S4 H+ _2 E0 l7 {3 M (2).@Around(“execution(. x2 a9 N. h0 S% g
* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)- @( g0 d' u* a# D9 a
// @Around(“com.javakc.spring.schemaaop.TestPointcut.t2() && args(str)”) w6 U+ F) P4 S, ]5 q; O6 a3 ]" Y
@Around(“execution(* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”), U/ H" l4 `" o$ s! E
public void testAround(ProceedingJoinPoint prj,String str) throws Throwable{" }- T1 u, k, o2 W0 @
System.out.println(“around1==========before1pointcut==>”+str)
) S. p2 Z$ B' P, r7 l Object obj = prj.proceed(); B/ a: Q; |2 F# H! }' X, L$ y, X6 q
System.out.println(“around1==========after1pointcut==>”+str);) [ n5 H% m8 i- h8 g) z% Q
}
3 `& [! e# [+ R) Q9 \ 5.4.3.@Before5 q$ G. K$ A4 z1 ?5 I
注解@Before在执行目标对象的方法前追加相应的功能
$ f% A& N; K8 r" E9 C" G 1 定义一个pointcut,通过方法名来作为pointcut的名称来引用
2 K. z* {( ~3 \8 Y& s6 K" ? (1).@Before(“com.javakc.spring.schemaaop.TestPointcut.t1()”)
+ A# g+ h0 b6 s5 Q2 O (2).@Before(“com.javakc.spring.schemaaop.TestPointcut.t2() && args(str)”)
7 H/ R6 I# U" f3 R3 @8 K/ | 注意args后的名称与参数名相同! S6 [4 h) X, n8 d5 g) J& M
2.直接引用匿名的pointcut
" ~- o& \4 P C* Z% _ (1).@Before(“execution(* com.javakc.spring.schemaaop.Api.test1())”)- _; ?0 O% u- y3 Z; x* P, W
(2).@Before(“execution(* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)
/ ]0 ?8 R0 u' e! [- a( e* \8 w 注意args后的名称与参数名相同
$ U' P$ _ P& A" l // @Before(“com.javakc.spring.schemaaop.TestPointcut.t2() && args(str)”): U+ B8 S4 L2 s# _. h% |$ b
@Before(“execution(* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)5 I# K2 K) ]0 r3 h( h' a
public void testBeforeParam(String str){' b$ e& f/ X, p7 m! {9 i
System.out.println(“before1=param=>”+str);
& h$ E1 w4 N2 o7 A1 j }
% r' e6 u7 D! C$ h/ y# ^. d
t8 u5 s s2 \" Z+ e0 Z5.4.4.@After6 C k9 ?2 A2 |" `
注解@After在执行目标对象的方法后追加相应的功能( n- M& q0 j0 [& V4 \' Q1 N
1 定义一个pointcut,通过方法名来作为pointcut的名称来引用( a X/ {& ^" u `
(1).@After(“com.javakc.spring.schemaaop.TestPointcut.t1()”)
$ C9 t- J2 Q/ \5 K* _ 2.直接引用匿名的pointcut
# B4 t7 Z/ ?# j9 r (1).@After(“execution(* com.javakc.spring.schemaaop.Api.test1())”)/ m+ ?# U/ `3 V) b# ~
@After(“com.javakc.spring.schemaaop.TestPointcut.t1()”)( v. R! g3 u$ {( j, \" B% \2 O) h
public void testAfter(){+ _, B A2 D/ A1 p! v6 y! s$ p
System.out.println(“after1== >pointcut”);8 a& R5 C9 j* e. h6 Z8 M
}1 l4 A* @& }& M' _1 [& ?
5.4.5.@AfterThorwing" k" b+ A5 ?8 R2 M; n& L
( p) [3 }/ z1 n" {
8 e$ A2 V4 K$ H& P" J4 C
- 描述一下spring中BeanFactory和ApplicationContext的差别3 M3 G: ?% o) ]4 f& v
; M& _* x M G! y( d3 a
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”);
, r8 h( Y! I+ X: }; [- 谈谈spring对DAO的支持, X. H6 u# P% T4 F# u. P) `: v
& i: s& i0 J5 i, H) W
Spring提供的DAO(数据访问对象)支持主要的目的是便于以标准的方式使用不同的数据访问技术。
/ f; {; s4 {; @. r 简化 DAO 组件的开发。
/ ]+ W9 O- c0 _- G z0 B, eSpring提供了一套抽象DAO类供你扩展。这些抽象类提供了一些方法,用来简化代码开发。
5 [/ S7 B% Y9 ? ~3 f1 I T IoC 容器的使用,提供了 DAO 组件与业务逻辑组件之间的解耦。所有的 DAO 组件,都由容器负责注入到业务逻辑组件中,其业务组件无须关心 DAO 组件的实现。
3 l9 H9 _. x1 z' P" m, ]" x 面向接口编程及 DAO 模式的使用,提高了系统组件之间的解耦,降低了系统重构的成本。9 c+ S3 w, ]6 u- l: J2 O
方便的事务管理: Spring的声明式事务管理力度是方法级。/ v, d4 e) A* I. n* n
异常包装:Spring能够包装Hibernate异常,把它们从CheckedException变为RuntimeException; 开发者可选择在恰当的层处理数据中不可恢复的异常,从而避免烦琐的 catch/throw 及异常声明。: b6 C1 Z; n7 k3 l0 A
2 | ~; p- x2 ]8 f4 R$ t, w/ J' J* a
3 [) E6 m0 [- `2 ?! d8 H- 谈谈spring对hibernate的支持
" r& o$ W3 G( @8 R2 F: L1 G5 O) R$ l) G: T- @
在所有的 ORM 框架中, Sping 对 Hibernate 的支持最好。如 SessionFactory 的注入、HibernateTemplate 的简化操作及 DAO 支持等。另外, Spring 还提供了统一的异常体系及声明式事务管理等。
$ b7 x2 n. c( {/ |" @5 c 一旦 Hibernate 处于 Spring 的管理下, Hibernate 所需要的基础资源,都由 Spring 提供注入。Hibernate 创建 SessionFactory 必需的 DataSource ,执行持久化必需的 Session 及持久层访问必需的事务控制等,这些原本必须通过代码控制的逻辑,都将由Spring 接管 ataSource, SessionFactory, TransactionManager等,都将作为 Spring 容器中的 bean。将这些bean 放在配置文件中管理。
3 i' _: U& Y9 k$ i+ K4 j! W+ V 1、通用的资源管理: Spring 的 ApplicationContext 能管理 SessionFactory,使得配置值很容易被管理和修改,无须使用Hibernate 的配置文件。详细配置如下:
9 @9 n: i2 P! |' d! {( C! V" a
' ^9 _6 Z' O# [5 @ class=“org.apache.commons.dbcp.BasicDataSource”>
5 v) Z4 n# Z: m0 m' ^( B1 r
# C4 A: X; B! p. v oracle.jdbc.driver.OracleDriver
5 r: L4 i3 o, f
6 j3 g& P) B5 _6 x$ h9 o" i
4 Q8 j2 T1 M. L" {: h1 G4 z# E jdbc racle:thin localhost:1521 rcl
* ]1 b0 d) i4 |7 B" b+ b 4 L/ [3 l1 E* U! ]; k, w
! X3 r& t9 Q2 J( k& g; e! m& i: x javakc2
; i. {( |; g$ K7 L! I- \6 c. e ( L& I+ s9 L1 v4 f2 p
" L* w0 F/ ~8 |1 d% f- O: W' S
javakc2# a5 X2 q- ?3 A) B& k
# N8 B" J3 P0 `1 D/ x3 J; k+ p4 ]; Q
7 Z' t/ M5 q* o/ M
9 W! D. z% D y7 X, W class=“org.springframework.orm.hibernate3.LocalSessionFactoryBean”>/ {: o7 y. F0 B/ L W7 i' \
* C5 y- R3 n3 W" U$ `& t# Q" a% c
; w/ ~. W9 {: p6 A% ~4 ]8 C/ {
' b2 v6 I, O2 T" P/ D/ Q com/javakc/spring/h3/UserModel.hbm.xml' k7 c# L9 d" p
* E6 f: K# I8 {+ |9 G* y" N; f
! T, T) F3 D6 y: l2 D4 s 3 N( R5 @1 Q2 n
( x2 t0 `4 Q+ j5 Z$ h) R: o hibernate.dialect=org.hibernate.dialect.OracleDialect
, y ?: h5 e0 L7 Y) I4 _& e
9 q- \8 c+ K. B6 S
+ q' S& a# t; w
% R d; s% H0 R9 c- t4 P- [$ T0 ]
. B/ V7 } ]1 @8 _ 3 Y# X3 s& |9 n6 O# `( u
; u' `; _* S. M4 D( k" d 如果需要使用容器管理的数据源,则无须提供数据驱动等信息,只需要提供数据源的JNDI 即可。对上文的SessionFactory只需将dataSource的配置替换成 JNDI 数据源,并将原有的 myDataSource Bean 替换成如下所示: class=“org.springframework.jndi.JndiObjectFactoryBean”>
$ v6 e; K% i1 K p, A- R0 j & ]& G) `6 g2 I
java:comp/env/jdbc/myds
2 g" L, o- h4 {% e ' D S% _7 _% T0 z: N9 K
2、有效的 Session 管理: Dao类继承HibernateDaoSurport后,Spring 提供了 HibernateTemplate,用于持久层访问,该模板类无须显示打开 Session及关闭 Session。它只要获得 SessionFactory 的引用,将可以智能打开 Session,并在持久化访问结束后关闭 Session ,程序开发只需完成持久层逻辑,通用的操作则由HibernateTemplate 完成。 3、统一的事务管理。无论是编程式事务,还是声明式事务, Spring 都提供一致的编程模型,无须烦琐的开始事务、显式提交及回滚。 建议使用声明式事务管理,Spring 的声明式事务以 Spring 的 AOP 为基础。可将事务管理逻辑与代码分离。代码中无须实现任何事务逻辑,程序开发者可以更专注于业务逻辑的实现。声明式事务不与任何事务策略藕合,采用声明式事务可以方便地在全局事务和局部事务之间切换。 Spring声明性事务有两种配置方法,一种是xml配置: S& ~2 M! i5 b$ G
1 p3 B$ J5 N! H* C; P7 S( Q7 S% v9 U
. k4 M0 r/ D# a* z, f% G" j6 C8 ]) E: L - ^; @$ S6 ^% i
4 Y/ o( q7 |# n$ |
7 F) I7 r7 p, V0 R o
, p" ~6 I- P" Y* N
2 B: _8 N+ Q* r8 d d 1 j& m7 q. q1 M
& u, k$ Y: P5 l( c" U* g3 v6 ~ ) E1 x' Q+ i: ]/ j7 ~# @$ M
' z$ C. P' `6 {
2 P! ?' F3 a" |' N. Y
" `4 g: o i6 l8 z) Z2 C& ~ 另一种是通过注解,在需要添加事务的类上注明 @Transactional
0 E- Y7 Y9 J9 {" }, |% U1 L" vSpring2.0之前事务的写法
' A% L4 f+ X) V" N6 u _: E. {2 ~ Z, M8 u1 r5 b$ C, I
+ y* L9 l0 ^5 y& d, U- T: m9 f
class=”org.springframework.transaction.interceptor.TransactionProxyFactoryBean”
: k$ n2 ~& P) z) l3 a$ p: e3 X
abstract=”true”>
$ a. e; k" v! n) @( N! Y/ m! d6 I0 a: p
& e' f. h3 ]/ O6 m: @5 ]/ `' g2 R
7 R$ e g2 S' V' f/ ]( ~
/ j: ?5 s9 \& ?6 M2 g. ?0 M PROPAGATION_REQUIRED,readOnly/ s/ L4 \# p9 `9 Z3 K. t
- v% [4 q& ^9 e P, B
PROPAGATION_REQUIRED
; K7 f9 c4 h0 Z# C
# \2 Y" p1 U t. {* O" d x; }! ]1 A% }2 R0 @
9 _2 R7 y( u8 W) \
; V5 U4 E9 b8 J |
3 \! d3 @, y6 B: N! f$ _+ X7 _+ e, S5 ~9 v
- 谈谈Spring对事务的支持1 B1 d' Y4 k" B2 z( F7 h- P
u t& G. R) H5 M4 @
! U% J1 }1 v& @* r9 J* K# c1、声明式事务管理:
1.流程:由客户端访问—-aop监控—-调用advice来追加事务 2.做法: 2.1 在配置文件的头中引入xmlns:tx 和schema的文件 2.2 2.3 注入数据源
( i5 ~& x- F1 K( U1 U7 ^$ v6 j) J; G' `7 k# l
/ K. F' K; X5 P
0 g8 R% g9 { f: ^% C# c/ r7 S( e t' W6 Z
4 P( f: L( s4 N) Y7 y2.4 由spring实现的事务管理,但需要注入数据源 , D1 V- L. P9 ]9 l+ P
+ X, K3 b% s$ V; g$ |
! W& D9 K1 ]3 k4 ]# k2.5 事务监控所有的方法(事务加强) * A* q4 N3 u: m6 V& o( N- k8 @& D( ?
8 Q# |3 u( Z" T: B; T+ t3 J( _' _" p$ B+ O6 C5 |
8 i+ j3 k1 j: D5 G6 ?3 p! u
- s$ t5 ]( l/ C( u- I$ y2 G2.6 定义切入点 " @! W$ L& |# T# U' w
, `9 }; u7 D$ j+ p" L f+ T$ q4 ?
6 s' m4 j) u0 U6 V8 L+ y6 M. h& n: k. j+ h
$ F" P! P$ @" T# S$ S
2、使用注解实现事务管理: 1.注解@Transcational (可以在类上,也可以在方法上) 2.在配置文件中同样需要注入dataSource和spring的事务管理 3.使用注解的方法来追加事务 注解驱动 ' k2 n+ \3 S2 @% A
. ^- \! _! b u# ]
如何在Spring中使用Hibernate的事务:- M+ ]3 V& k/ R0 c( n
4 M3 B( X5 i" b+ n1 o7 m. G
3 S2 l" Y1 L; j1 k5 A* R4 Z8 K3 Z, S
; x, G3 S' ? G( c
如何在Spring中使用JTA的事务:
/ b; h* b5 W" x, R
C' v1 p2 k$ @3 H |