Spring& X0 Z# ~7 J9 {
- 是什么?
0 {4 }( @% F9 I, n
! `. N. z( U3 A/ t9 v
Spring是基于JEE的轻量级的应用框架 2 I9 @; P: x% N( P- g, u! r
- 有什么?
- ~8 n) V8 x7 [5 S0 P4 w* G; I2 A' Y# s
4 N& r2 @% t2 s
每个包的功能: Spring MVC:spring 本身提供的web 框架 WEB:集成其他的web 应用的框架,或者说是对其他web应用框架的支持。如struts,webwork JEE :集成一系列的jee的技术(对JEE技术的支持) DAO:封装了JDBC;(对JDBC的支持) ORM:提供了对ORM工具的集成(支持) AOP :面向切面编成 CORE:spring的核心包,提供bean的工厂和IOC容器 - j( z p0 A) d% @# E
- 能干什么?
# e4 S. Q) T0 b. m% P4 G; d) Y( ?( S0 ]1 b& h
把一系列的jee的技术有效的组合在一起形成以良好的系统
: ~$ d5 o" v% S% O4 A- 怎么用?
' t% ?1 f# x1 b3 m! v! U1 x: C
- |" F& Y! F; r0 o* w/ ^- H- 搭建web工程,引入spring的jar包
6 x; ?# V# i+ s) r - 在web.xml中添加如下配置3 P; m- E% p6 R! P3 O- B1 z2 [. j% k+ m
8 K. R2 n. v; C. {( f# Y/ D 0 O( O, L: e; x9 w! o; r; X$ h6 [) V6 _
- S% E4 i, b7 j$ [& s% Z9 }
contextConfigLocation
' G1 `4 H* D& I$ W3 b1 m classpath*:applicationContext*.xml
$ \5 ~3 h8 H a J . c/ k9 B: H8 ]0 _: B1 _' v0 q
, d. m- [# i4 w' _) c3 [
struts2! k. v4 I& Z& z/ k/ W, W
; K$ r+ d& D$ X8 j$ H
org.apache.struts2.dispatcher.FilterDispatcher/ S2 O z: w \- E
) b+ J6 B% D" R+ z$ ~ ' [) o0 ?. k1 c9 g8 b
' L4 E# d8 K! w! d8 R( L8 Q/ Z: W2 ~
struts2, L6 n* ^& ^: t- o \' @( Y
/*
2 A, i! B5 d3 p* @1 J8 \( L. |* Q% t
- M8 O# |% x4 A( }
' O6 E8 o. W( Q$ ]# n5 ?/ E1 ]
+ ?$ w: j* F. t& x
org.springframework.web.context.ContextLoaderListener
- T3 L! e! S3 v7 ^- t & D' Y7 w$ }, m( B! B9 L
- 部署
4 g# j) S6 [1 h6 o- y7 I; |
/ k2 |; m5 t3 c2 W _ # F3 l5 [% a* i# u6 O( L& h
, ~7 \ W% E% }# n$ A8 i% w
* C5 H$ U# m9 `5 f. ^4 G8 T% Q E- 容器和bean
% L: D" w. [7 m k. I
Bean :是指受spring的ioc管理的对象称为bean 容器 :(与jee的容器类比) Jee :提供组件的运行环境和管理组件的生命周期(不能单独存在) Spring :提供bean的运行环境和管理bean的生命周期(可以单独存在) {8 t5 m- p8 S
" r1 T; c- H( s+ d# A* M6 p- DI依赖注入
# L. h5 T6 K" _! @! D6 G
1. 应用程序依赖spring注入所需要的对象 IOC和DI是对同一种事情的不同描述 2.setter注入: 在配置文件中将接口的实现配置为bean在应用程序中注入bean 例如: 在配置文件中
+ F- {% V- G6 D1 U7 z
0 O7 d9 w& ]4 {3 Z
4 E3 H. D7 d7 S3 q R在应用程序中 Public DBDAO dao ; Public void setDao(DBDAO dao){ This.dao = dao; } 3.构造器注入 ( N: {9 |4 W. _2 N4 v, G
4.ref 表示参照其它的bean 在参照的过程中一定要注意死循环 5.自动装配———–〉no 自动装配根据名字来匹配相应的bean 尽量不要去自动装配 6.lookup注入 7.singleton 1.单例模式是整个的jvm中只有一个实例 2.spring的singleton是指在spring的容器中只有一个实例 一个生命周期中只有一个实例 8.DI的优点: 1.程序被动等待,强化面向接口编成 2.切断了对象或组件之间的联系,使程序的结构更加松散,运行和维护更加简单
& A8 |5 S% B# W$ v- Aop面向切面编程/ R7 z; R- B/ y1 H6 k
8 i) x. I+ [. D! U
1.AOP面向切面编程 一些较好的模式或者是示例—-范式) G$ o) b9 T/ d ~
切面:一个切面代表我们所关注的一系列的共同的功能点(模块之间的共同的功能点) 2.AOP的思想: 主动—->被动(追加功能)' F0 p/ ?7 i# v9 J _5 \
3.AOP 的概念; F( O" D# [; Q4 g
1.切面 :我们所关注的功能点 2.连接点 :事件的触发点(方法的执行) 3.通知 :连接点触发时执行的动作(方法) 4.切入点 :一系列的连接点的集合 (连接点的模块化) 5.引入 :扩展的功能 6.目标对象 :包含连接点的对象 7.aop代理 :实现机制 8.织入 :把advice和目标对象连接起来 4.AOP的事件机制. t/ Z+ P: |) b$ B2 e" p, l
1.通过切面找出一系列共同的功能点 2.找到目标对象(在标准的spring 中 接口的实现类为target) 3.找到切入点 4.确定连接点 5.通知spring AOP,查询xml文件,通过代理找到advice。 6.由aop代理来实现动态织入
% Q( P$ l" j. h9 O2 r7 X; s! a# x# B7 `( s# Y3 O5 J w- z0 l& H
2 B# i. S" Q: }$ z( v) z. R+ J
! ^9 H! M8 i) q P
0 |4 n, O P" A( |9 i4 P, X6 H
: J1 }. b+ p- f; h. m
K# T; e6 z+ A" W. y5. AspectJ
- |6 d- ^5 [5 |) w* T 5.1.在xml中配置比较烦琐
2 y5 n3 T$ G2 L# A# W 所有的入口必须从一个代理(ProxyFactoryBean)开始
# M7 R5 m. @* L5 n9 y 3 {1 b4 u/ c( d# @. a" U! q5 X
% x. x$ ^* e% n- T
2 i" a* c% n- ^& U! X5 p) [
8 ]$ Q. d9 X7 H" j( Z0 n8 _/ n( e, r7 {, k- n/ @0 x4 t
) _! I2 w. ~) z) M+ z3 \# B ' [. k- J: O" G% ~
/ V1 f0 {8 E+ V) @( L
expression=“execution(* com.javakc.aop.MyTarget.t*())”/>
& p0 E5 J5 D* A2 P; t( a6 t. {* `, Z 0 b& m8 v: G8 }4 Z6 `( V; X1 P
: B0 M& p3 I, W" v& B
9 w1 W- `) D9 c7 E& H ( \8 `* v" p. U, `
s6 f8 O% R: d$ J3 F/ k0 U( _
5.3.使用注解的方法相对简单
/ s/ b1 }0 E% j8 b8 | @AspectJ的基本语法* S2 k/ U$ C4 L# l2 c( M
1.@Aspect声明一个切面,将一系列的共同的功能定义成一个切面
- D( v, ?* k1 b( s 直接在类上定义@Aspect+ b9 A! ?. M; E* {
2.@Pointcut声明切入点' X- R8 }! u" [# l; K l: k6 W
2.1、用一个专门的类来定义pointcut,类中的方法名就是该pointcut的名字4 X$ a T# l( Q" M
2.2、可以使用匿名的pointcut
: D9 \4 i4 c3 t* l; W, Y) G 2.3、执行切点的几种方法1 [$ |) \9 ]2 n l& s% g) R# S% d
2.3.1 execute(public * 包结构.*.*.(..)) 可以指定到具体的方法
$ q8 p7 h- W( j+ ^ 2.3.2 within 指定到包,不能指定到类* ^( B$ j0 m Z, q% m: T
within(”com.javakc.spring..*”)+ T' g9 Y0 q# K4 L2 p+ Y
2.3.3 this 指定到实现接口的所有的实现类
& ]& q4 }* h/ _ 2.3.4 target 指定具体的实现类
8 ?# m8 a8 A; A0 o1 l 5.4.advice的五种类型的示例
, B" C7 w1 z0 d) r; A& B- w 客户端必须从接口走才能得到监控,实现想要追加的功能 ?- {; K7 i% l3 ]; m0 B8 x, {
5.4.1.@AfterReturning(pointcut=”” returning=”retVal”), f8 B7 {7 g7 Q; Q
追加的方法的参数名字一定要与retrning的名字相同
8 K. x& S* V7 c4 ` 在注解@AfterReturning中必须加上pointcut和returning两个参数
& [2 Z+ \) }3 n. z0 S pointcut指所要监控的目标对象的方法5 n/ N6 X9 U. q* r6 U
得到目标对象的方法的返回值,来作为参数,进行下一步的处理,参数没有顺序,按参数的名字进行匹配
5 n) Z" \6 f# @ 完成追加的功能6 @% h$ f4 L# @( A
1 定义一个pointcut,通过方法名来作为pointcut的名称来引用$ _/ A7 _5 D8 g7 @8 @# H0 @: Q, ?, d
(1).@AfterReturning(“com.javakc.spring.schemaaop.TestPointcut.t4()”)- a4 i5 ?4 ?# A- @ T6 a9 W
(2).
+ I- U# x, |; `7 w) u9 A/ c 2.直接引用匿名的pointcut
5 e% r4 c; w8 ]; `! w2 k (1).@AfterReturning(“execution(
4 P! ~% F3 O( r9 `% ^( o * com.javakc.spring.schemaaop.Api.test4())”)7 u/ V$ ]/ U1 o$ @9 D. v
(2).@AfterReturning(pointcut=
5 \# s7 O6 p, O- N “com.javakc.spring.schemaaop.TestPointcut.t4() &&
+ ]" Z+ d+ i7 T& u9 e- n args(str)”, returning=”retVal”)
& Y4 I7 f0 E j% S! X @AfterReturning (pointcut=”com.javakc.spring.schemaaop.TestPointcut.t4() && args(str)”,returning=”retVal”), \ f' ^6 ^6 ~
public void testAfterReturning(String str,Object retVal){
/ `& K$ |/ j/ ]5 F System.out.println(“afterReturning1=>”+retVal+”=>”+str);7 N* c5 y: D; V; [/ o) C! i/ b" i
}
3 M; ?0 M- z, E8 w p- p# c 5.4.2.@Aronud
! _) \7 a, ]! B6 } 注解@Around环绕追加功能;$ z% p. ]2 S! h2 Y( D) e8 e' O
在执行目标对象的方法的前、后追加功能;" |& K, a! r7 I9 }( P/ [
必须有参数;第一个参数的类型必须为ProceedingJoinPoint;7 Q* \/ m2 F- O$ y) F2 N
通过ProceedingJoinPoint的实例的proceed来调用所监控的
9 W1 r& W2 m6 K [ 目标对象的方法
( H$ o. {6 T8 _$ t: u 1 定义一个pointcut,通过方法名来作为pointcut的名称来引用
4 o, _* N! \, k (1).@Around(“com.javakc.spring.schemaaop.TestPointcut.t1()”)
& O1 J( N t4 X) B4 F3 p (2).@Around(“com.javakc.spring.schemaaop.TestPointcut.t2()
+ B2 X% s# ^4 K && args(str)”)
% D& o @& T; C j1 x0 N6 d2 D 2.直接引用匿名的pointcut y g3 p+ }6 S5 B! y
(1).@Around(“execution(9 F' a) s- H* R/ L% Z. V4 b2 P5 d
* com.javakc.spring.schemaaop.Api.test1())”)
H0 J( e/ {: B! U4 M (2).@Around(“execution(
[) {- A3 @. }/ ` * com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”): W% a8 g% Z( R" g
// @Around(“com.javakc.spring.schemaaop.TestPointcut.t2() && args(str)”)- r/ p( |' |. x2 a
@Around(“execution(* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)3 d/ l. f m4 L' Z* X
public void testAround(ProceedingJoinPoint prj,String str) throws Throwable{
. O: L- K ]" A$ a System.out.println(“around1==========before1pointcut==>”+str), u9 f1 c/ E/ |/ I( |2 }# u
Object obj = prj.proceed();4 W. j9 p& s2 p9 [ [7 D7 V9 C+ F
System.out.println(“around1==========after1pointcut==>”+str);+ Y j$ o8 j$ W8 e1 t+ U) k' ?
}6 o, c! @8 `4 T
5.4.3.@Before
8 l1 B+ A2 \. Q' Y 注解@Before在执行目标对象的方法前追加相应的功能/ ~# I+ p N8 q8 |" x
1 定义一个pointcut,通过方法名来作为pointcut的名称来引用
# r) F. ] ?- R! x& y (1).@Before(“com.javakc.spring.schemaaop.TestPointcut.t1()”)1 _0 U7 g% H) Y0 S
(2).@Before(“com.javakc.spring.schemaaop.TestPointcut.t2() && args(str)”)+ f* C, D$ C9 M& l1 c2 F! h
注意args后的名称与参数名相同
3 }6 m& D/ q- ] 2.直接引用匿名的pointcut/ q. W/ ~- {5 O
(1).@Before(“execution(* com.javakc.spring.schemaaop.Api.test1())”)
, T9 P F3 w S (2).@Before(“execution(* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)
; n' X2 {; z5 U, q 注意args后的名称与参数名相同
1 @2 Y8 q5 I# m1 ~4 w6 a // @Before(“com.javakc.spring.schemaaop.TestPointcut.t2() && args(str)”)6 l3 ^1 ^2 [* j0 k1 z
@Before(“execution(* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)5 A$ j0 y' A! B
public void testBeforeParam(String str){ b; v& `: H; f, n; [1 A8 f7 a, ?
System.out.println(“before1=param=>”+str);
7 f; l5 G' ?" @2 c: n# F: V2 c7 | }
6 Y) s( s* `7 a$ X% L6 E/ S
* j! |3 d+ o5 K" x5 `9 y1 j5.4.4.@After
) J* c/ w8 M& J/ i/ a( D' O7 q 注解@After在执行目标对象的方法后追加相应的功能
* o& c9 e6 @$ p 1 定义一个pointcut,通过方法名来作为pointcut的名称来引用, X6 E( n- [* ~3 J$ X7 [- z) p
(1).@After(“com.javakc.spring.schemaaop.TestPointcut.t1()”)
, ?1 {0 c2 L* ] 2.直接引用匿名的pointcut, s9 D9 ?: R: |& \' R
(1).@After(“execution(* com.javakc.spring.schemaaop.Api.test1())”)* k) C$ ?( z7 C
@After(“com.javakc.spring.schemaaop.TestPointcut.t1()”)
: @8 d. F4 v& q+ o1 F public void testAfter(){
. P" `9 ]1 I4 Z' t System.out.println(“after1== >pointcut”);
" I6 p& c; w( z }
% e6 y& B# r: B 5.4.5.@AfterThorwing
}; B! Z! N; G- b2 x
0 z9 N2 t6 v$ H. V# u. L/ G" [) `, ^7 J7 P- v) a+ L
- 描述一下spring中BeanFactory和ApplicationContext的差别
6 u$ E! I: a+ {! A# s* ]8 c9 h8 K" `/ W+ M
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”);
& s$ S) R( d9 }+ `( D- 谈谈spring对DAO的支持
. X) y) C# T2 A# p, Q7 E# l y8 _" p+ w9 y6 {5 H9 H
Spring提供的DAO(数据访问对象)支持主要的目的是便于以标准的方式使用不同的数据访问技术。; l" B+ S/ |. y8 Y; b, o
简化 DAO 组件的开发。
6 O- [0 R# G1 k8 @: dSpring提供了一套抽象DAO类供你扩展。这些抽象类提供了一些方法,用来简化代码开发。 y d% x: { W R B9 D9 P
IoC 容器的使用,提供了 DAO 组件与业务逻辑组件之间的解耦。所有的 DAO 组件,都由容器负责注入到业务逻辑组件中,其业务组件无须关心 DAO 组件的实现。: C0 x5 N1 z! c6 Q
面向接口编程及 DAO 模式的使用,提高了系统组件之间的解耦,降低了系统重构的成本。. B* o" o+ Q8 q4 [5 P( ?
方便的事务管理: Spring的声明式事务管理力度是方法级。2 P, ^3 F( k4 N( x0 M, c
异常包装:Spring能够包装Hibernate异常,把它们从CheckedException变为RuntimeException; 开发者可选择在恰当的层处理数据中不可恢复的异常,从而避免烦琐的 catch/throw 及异常声明。) T5 m9 {) F4 k k8 Y+ q
; z# M: _* o/ }2 q0 [+ d1 k+ q$ ]. J: [
; D4 J0 G" b0 b
- 谈谈spring对hibernate的支持
% |7 B& C% g7 L( @7 n) j* Y2 I; w1 J E, o# c( i
在所有的 ORM 框架中, Sping 对 Hibernate 的支持最好。如 SessionFactory 的注入、HibernateTemplate 的简化操作及 DAO 支持等。另外, Spring 还提供了统一的异常体系及声明式事务管理等。! V1 t! v8 X. `3 w
一旦 Hibernate 处于 Spring 的管理下, Hibernate 所需要的基础资源,都由 Spring 提供注入。Hibernate 创建 SessionFactory 必需的 DataSource ,执行持久化必需的 Session 及持久层访问必需的事务控制等,这些原本必须通过代码控制的逻辑,都将由Spring 接管ataSource, SessionFactory, TransactionManager等,都将作为 Spring 容器中的 bean。将这些bean 放在配置文件中管理。4 K( a2 f( C0 r) H: l6 v8 Y
1、通用的资源管理: Spring 的 ApplicationContext 能管理 SessionFactory,使得配置值很容易被管理和修改,无须使用Hibernate 的配置文件。详细配置如下:; `" k. t' ~: }! c+ q% i
3 ?" o' N/ T9 p0 C k4 M2 |0 v) A% C class=“org.apache.commons.dbcp.BasicDataSource”>
1 K& y4 F9 X o, h , Z$ J0 S" P& b9 j! s+ m! O
oracle.jdbc.driver.OracleDriver
x# _+ Y2 [! `; G) m0 k ' ]# K9 E9 E9 M d' `
3 B) `: U Y* w% |, {" d& T jdbcracle:thinlocalhost:1521rcl
+ L3 c* B6 m4 f# w: C; U$ \
! a9 J$ Y1 G Q; b ?$ E / D. B! M* R: T3 h8 X0 s( ~
javakc2
8 {+ }0 _1 X+ [1 T8 H4 ^
* _( [7 X; p+ A. d/ K% J
: ~ Q% `. A9 K! m# z javakc2& G" G* F! C1 B& X" F5 U
4 ^3 o' ^: C7 \7 t3 o
1 T6 c& `/ K4 t2 F* C* k
i+ o4 |$ R. l1 i$ A
class=“org.springframework.orm.hibernate3.LocalSessionFactoryBean”>
* x; p* `- ~! R3 W) d/ t 9 B( W" |! H1 k3 n1 i/ H1 g5 q
" v) {( j; b% P$ ^. `9 l
. M: ]0 k2 H4 ?8 U4 K com/javakc/spring/h3/UserModel.hbm.xml! ]9 Z8 @/ [! a+ B8 X. V2 K' A
- _; ~/ g' b' i" G
3 R3 ]: Z# _. ~. v
& A5 T8 M: z7 j7 V+ [
, T3 }! s4 P- v
hibernate.dialect=org.hibernate.dialect.OracleDialect
8 ~ n9 i0 L3 \
* q7 e Z C: q6 P- M [
1 Y8 ~# J! y) B/ p 1 s( f: ?) a9 W: c4 f4 P
; n! Z# u# b* q; ~
# \$ t2 Q" g. k, K5 q9 R/ b
" k5 F/ f9 V4 D8 \+ [ 如果需要使用容器管理的数据源,则无须提供数据驱动等信息,只需要提供数据源的JNDI 即可。对上文的SessionFactory只需将dataSource的配置替换成 JNDI 数据源,并将原有的 myDataSource Bean 替换成如下所示: class=“org.springframework.jndi.JndiObjectFactoryBean”> T! k9 P% g9 D; K
( E- M- f: f+ N; V
java:comp/env/jdbc/myds! N, `+ v% b, O
) R* G& u- ~, }/ Y1 t0 i4 Z
2、有效的 Session 管理: Dao类继承HibernateDaoSurport后,Spring 提供了 HibernateTemplate,用于持久层访问,该模板类无须显示打开 Session及关闭 Session。它只要获得 SessionFactory 的引用,将可以智能打开 Session,并在持久化访问结束后关闭 Session ,程序开发只需完成持久层逻辑,通用的操作则由HibernateTemplate 完成。 3、统一的事务管理。无论是编程式事务,还是声明式事务, Spring 都提供一致的编程模型,无须烦琐的开始事务、显式提交及回滚。 建议使用声明式事务管理,Spring 的声明式事务以 Spring 的 AOP 为基础。可将事务管理逻辑与代码分离。代码中无须实现任何事务逻辑,程序开发者可以更专注于业务逻辑的实现。声明式事务不与任何事务策略藕合,采用声明式事务可以方便地在全局事务和局部事务之间切换。 Spring声明性事务有两种配置方法,一种是xml配置: ' E# w3 b( E/ m; A/ P4 t) @# M
# ~5 D# m* I |! @
9 }$ I3 c8 ~- _' Y, b6 g9 S" M
' D, k/ M& h0 Y8 R
8 m% A1 x8 x* q 2 S9 I% q5 r' Q$ W1 y: }7 C
/ ^3 t" h3 G' |- u; F- M) y9 ? 0 m3 |4 b4 x3 a# t
1 \5 A8 `. o& F1 Y / e! t( M/ Z2 B' x F- ]
U- i2 ]: v% {3 g1 {! l5 I ( R& S( _+ j/ {7 W! Y8 B+ ]
+ |9 p4 ~* b! X9 X( p: o/ O
p3 ^, C' G2 @; o' l% D
另一种是通过注解,在需要添加事务的类上注明 @Transactional 1 _$ ] n" Z2 \; a* Z& a: L
Spring2.0之前事务的写法
- P6 Y* m5 S; l0 k' @ ~( ?3 m5 Y2 E; b+ x- |
# i0 q+ ^7 a; b0 _9 a
class=”org.springframework.transaction.interceptor.TransactionProxyFactoryBean”
0 `* [1 z5 c& X' Q7 Y J8 Z/ y, k
" A; c" ~+ ^+ `0 z/ Y2 ^$ R abstract=”true”>
. Q/ V. h% f' V- m9 P. f D
+ u7 d/ D9 y' z8 A4 K& v( M
4 O5 b1 p, g4 F3 o
$ g/ F) Z9 ^# g
; j) ^- }& l: ~) {+ R PROPAGATION_REQUIRED,readOnly
7 a+ U# j0 w# O/ w
/ e0 _) p! a6 k- | PROPAGATION_REQUIRED( G( _6 R7 x% d) e' S
& r$ U" q5 [/ O9 R' Q" ~
0 o7 M* v/ ^8 f! m. y5 N( n* M
: f# R/ U+ M8 j- G0 P9 @ [: D( v# `" B
| ; G: x/ P# |( Z7 i2 c& b* s" y
; m4 I; j' z1 y" g1 n( @" a- 谈谈Spring对事务的支持
; @1 C" {% H9 m& j, T2 |6 a- ^, R5 `
4 n4 i( E; t: f. ?' n
1、声明式事务管理: 1.流程:由客户端访问—-aop监控—-调用advice来追加事务 2.做法: 2.1 在配置文件的头中引入xmlns:tx 和schema的文件 2.2 2.3 注入数据源
o* f/ @; m9 ?/ ]) \) Q/ g* P$ r5 t
/ J) s) }/ o ]) F+ ~
M# M; j- k1 v
- H* J! @: J) y! O+ O' z6 d+ Q4 m! D) y; e/ h/ B% U# N+ M# T q
5 u4 C3 O% ], h0 k$ v
2.4 由spring实现的事务管理,但需要注入数据源
) [$ p' C" `3 }, h3 ~. E+ M6 R6 _& e* [3 [: T) @, B0 b- h$ ^
: F- B- s4 {9 k: ?: H. B: @
2.5 事务监控所有的方法(事务加强) ) e; }( i, G, Z# S$ A' n. s
4 W1 T r% g- P! [% d: t
! D6 A5 n( [3 r1 J3 ~
' z* W) E9 S% @6 b% N* [. g8 c0 W5 \3 B" L) ?
2.6 定义切入点 0 }4 L8 S' N7 g
! V1 s7 Y( ^ |4 {
8 J, v& a1 @( U0 V7 \0 O! {* T( N/ p3 l6 N
# {& g' s8 {# ~3 S" u s2、使用注解实现事务管理: 1.注解@Transcational (可以在类上,也可以在方法上) 2.在配置文件中同样需要注入dataSource和spring的事务管理 3.使用注解的方法来追加事务 注解驱动 . ~( n' x/ z }4 f0 ^+ r+ J
" T: C" |' t8 i- [( X8 ^; c如何在Spring中使用Hibernate的事务:
# G8 G( ~- P0 O: } D% |8 f3 } u
' y4 L1 m7 H: E# F* e
$ W1 S1 |1 Y$ x- N+ [ % e8 [0 }3 y# q/ |8 y3 h! A# y
如何在Spring中使用JTA的事务:) Y$ x8 [4 ]+ U; P, V8 {
" z9 p& b% k! c8 f
|