Spring
: n* f* N, k; l! q- 是什么?
* h: e9 U" C" `
9 O4 A6 n3 L/ [: _9 l4 c+ x6 k, s
Spring是基于JEE的轻量级的应用框架 6 t, m! ^% i5 k6 N
- 有什么?
% S! D% |' s, [ q# Z: o
* u5 T) E9 f8 R6 l' F # D/ ?' ]* N i+ b
每个包的功能: Spring MVC:spring 本身提供的web 框架 WEB:集成其他的web 应用的框架,或者说是对其他web应用框架的支持。如struts,webwork JEE :集成一系列的jee的技术(对JEE技术的支持) DAO:封装了JDBC;(对JDBC的支持) ORM:提供了对ORM工具的集成(支持) AOP :面向切面编成 CORE:spring的核心包,提供bean的工厂和IOC容器 + |1 w! y! z( c1 T! U
- 能干什么?1 w5 p- C1 `9 ]) ]2 @- J4 ?4 X
/ g+ f! e+ t, ?5 `
把一系列的jee的技术有效的组合在一起形成以良好的系统 5 s8 m$ W% f; U0 L- B3 H' T
- 怎么用?
6 g: K3 @& g. L
8 l3 J/ ?3 ?* t7 I' ?1 u- 搭建web工程,引入spring的jar包
6 L/ y! o0 u8 \' A' O - 在web.xml中添加如下配置* T* y* e" i- U9 b% }
" ?: x) u* i1 Y ! r( b' S; K. ^$ C) k
5 g9 b6 g" d. @! r/ e
contextConfigLocation
, Y* I8 t$ K* j8 ] classpath*:applicationContext*.xml$ @2 K- g* z$ P |
* Z6 Q2 w" S1 |! W4 I5 ?5 \ 0 k% g4 \0 f# L0 {, A% S" @! k( C
struts22 |+ ~5 j. L+ g0 w; m
; r( ?1 V* t- ]$ G
org.apache.struts2.dispatcher.FilterDispatcher
1 E8 g% v6 M& c* y8 U
& n4 ^! l: V! L% _ - {0 j2 U# `0 X/ c6 ^; u
. N1 u5 p: ^5 g' G struts2
) M' [5 `" f+ x l f /*2 |/ @/ ?( S1 g4 w! s5 F
" u% u' z3 ?# A1 X+ x
8 H$ E: o* h2 l1 h3 z
/ q. L# L# k d5 a9 a org.springframework.web.context.ContextLoaderListener, w% F! ?* F8 x
$ w; V9 ]$ L! n0 Q; r
- 部署
8 p4 t/ ]* ^8 B; U9 ^! t# S7 K: m" m! O" l/ m; T, |
+ T. O5 v1 r" W! F2 i2 N
" J0 z( u4 `( _. t- W* M: h" W8 \0 J) @" G: ~! i* A# z; q
- 容器和bean
* f# z2 P' @5 z0 W4 r$ P
Bean :是指受spring的ioc管理的对象称为bean 容器 :(与jee的容器类比) Jee :提供组件的运行环境和管理组件的生命周期(不能单独存在) Spring :提供bean的运行环境和管理bean的生命周期(可以单独存在) + ^# t, t7 R! I, `
% |0 t; V; s5 Y {+ g3 S' @
- DI依赖注入
; N* s. u0 F# X( R. z5 S6 `
1. 应用程序依赖spring注入所需要的对象 IOC和DI是对同一种事情的不同描述 2.setter注入: 在配置文件中将接口的实现配置为bean在应用程序中注入bean 例如: 在配置文件中 1 T& d: s$ D9 ]' Z$ S
* T3 r \( E7 J2 i
0 i. G; F6 P) l/ E2 J" m4 y
在应用程序中 Public DBDAO dao ; Public void setDao(DBDAO dao){ This.dao = dao; } 3.构造器注入
3 j: M% q \( i3 q4.ref 表示参照其它的bean 在参照的过程中一定要注意死循环 5.自动装配———–〉no 自动装配根据名字来匹配相应的bean 尽量不要去自动装配 6.lookup注入 7.singleton 1.单例模式是整个的jvm中只有一个实例 2.spring的singleton是指在spring的容器中只有一个实例 一个生命周期中只有一个实例 8.DI的优点: 1.程序被动等待,强化面向接口编成 2.切断了对象或组件之间的联系,使程序的结构更加松散,运行和维护更加简单 & i& _) Z& k% {8 f0 x% P% j$ w3 [
- Aop面向切面编程5 m; _6 X3 J0 T6 s4 \5 l
3 W9 k( W8 q' E* f6 n. _* w) S
1.AOP面向切面编程 一些较好的模式或者是示例—-范式
* r5 q0 n h/ _6 N9 Z0 ~ 切面:一个切面代表我们所关注的一系列的共同的功能点(模块之间的共同的功能点) 2.AOP的思想: 主动—->被动(追加功能); c E8 ?& m& G) y r0 G8 d9 D+ q
3.AOP 的概念
k- Y4 K7 s2 z" k" b 1.切面 :我们所关注的功能点 2.连接点 :事件的触发点(方法的执行) 3.通知 :连接点触发时执行的动作(方法) 4.切入点 :一系列的连接点的集合 (连接点的模块化) 5.引入 :扩展的功能 6.目标对象 :包含连接点的对象 7.aop代理 :实现机制 8.织入 :把advice和目标对象连接起来 4.AOP的事件机制1 a8 n" c; W v2 b/ T# P
1.通过切面找出一系列共同的功能点 2.找到目标对象(在标准的spring 中 接口的实现类为target) 3.找到切入点 4.确定连接点 5.通知spring AOP,查询xml文件,通过代理找到advice。 6.由aop代理来实现动态织入 & r/ M" H# R& b$ v$ N
9 e5 D9 v5 n4 N' u4 b+ t+ U2 P6 T/ u+ _$ }
. d8 U$ m4 L. u2 k# E
4 l: x9 G8 n# L0 z4 Y- D7 H$ h {& ~" V! y" a! V
( w6 h& J% r) ]1 s
5. AspectJ
N( u" b! ], l. c* o 5.1.在xml中配置比较烦琐- N J- W3 H% d! C) J/ n
所有的入口必须从一个代理(ProxyFactoryBean)开始
) c Z9 N1 n" i) X % p5 c+ n7 J" P2 f
" ]) X9 A3 }/ b' S
9 g7 l g# R& N% _; n
% U6 d2 z( m" h$ E
% t, _$ B* r/ B1 D$ a" W
& Z! e2 ~( O* P( P
$ A# ~" H' ~& m, x- }' l# H
' m1 I4 ~4 _; U# g; Wexpression=“execution(* com.javakc.aop.MyTarget.t*())”/>% e2 Z- ?* ?6 \1 [/ V% T
" A" v) G" `5 }+ {. L! ?
! {$ H$ D+ W3 Z
7 W, G/ x2 h9 i
. _: m M; n$ _' l( A
7 [0 a, R2 U. I5.3.使用注解的方法相对简单
+ @3 O+ I" B- ~8 R: f/ I+ ~! y" [ @AspectJ的基本语法4 i3 z! A9 x. [: J2 {4 [6 b
1.@Aspect声明一个切面,将一系列的共同的功能定义成一个切面$ n) M$ ^9 Y' [& T5 k) \, Y8 B: b, P0 b
直接在类上定义@Aspect
- B8 P3 ~9 a, R5 J* { 2.@Pointcut声明切入点
2 [% @1 o9 ^( i/ {& x% m 2.1、用一个专门的类来定义pointcut,类中的方法名就是该pointcut的名字
- E) T2 ]4 \" o$ f/ R! C6 X 2.2、可以使用匿名的pointcut
6 D$ a- i& f# s 2.3、执行切点的几种方法2 U* D' B7 u) c9 ^% i7 |/ x( T
2.3.1 execute(public * 包结构.*.*.(..)) 可以指定到具体的方法
/ A$ D1 t" D( `! j+ \9 o; u0 S6 m 2.3.2 within 指定到包,不能指定到类- h9 U+ A' O/ h1 J" [4 g$ F
within(”com.javakc.spring..*”)8 x2 s' j* m3 [2 h& q3 a$ {
2.3.3 this 指定到实现接口的所有的实现类
& V& B& @+ x# q+ w! \ 2.3.4 target 指定具体的实现类8 Z3 F5 a4 Z# x5 H/ j H+ H# |: V
5.4.advice的五种类型的示例) u5 ]) }9 w; h
客户端必须从接口走才能得到监控,实现想要追加的功能
& O, O9 x R! x, ]" b9 j 5.4.1.@AfterReturning(pointcut=”” returning=”retVal”)
0 f# v8 f2 W( Q" w9 u& H 追加的方法的参数名字一定要与retrning的名字相同
! [& k# J& b3 J: ~. z6 g 在注解@AfterReturning中必须加上pointcut和returning两个参数
3 v0 D1 ?+ O; ]( T pointcut指所要监控的目标对象的方法$ h( n* N" Y- t' E) C$ }
得到目标对象的方法的返回值,来作为参数,进行下一步的处理,参数没有顺序,按参数的名字进行匹配* Q" o7 N8 Z1 B! C
完成追加的功能
* a" W; \4 b+ i% q' F& ]* I 1 定义一个pointcut,通过方法名来作为pointcut的名称来引用
& M l; a6 }& z8 | (1).@AfterReturning(“com.javakc.spring.schemaaop.TestPointcut.t4()”)
& l* c$ r0 M- n+ |) F, o (2).) w8 s: p! ^! c6 v) \
2.直接引用匿名的pointcut
- L3 y: k4 K# X2 O7 q1 k$ d (1).@AfterReturning(“execution(
8 h: K* M1 m& j2 m4 } * com.javakc.spring.schemaaop.Api.test4())”)
9 \0 Y$ D( {, V, l$ i* a4 n (2).@AfterReturning(pointcut=$ L3 n( i+ W. P/ |3 Y" m
“com.javakc.spring.schemaaop.TestPointcut.t4() &&; `1 s$ j, C ~ ~2 y4 [
args(str)”, returning=”retVal”)
' T" {- O( @$ ^) u; b" H* F @AfterReturning (pointcut=”com.javakc.spring.schemaaop.TestPointcut.t4() && args(str)”,returning=”retVal”)
0 ?- T ?. r/ }; @; h public void testAfterReturning(String str,Object retVal){( V$ S' x l- ]
System.out.println(“afterReturning1=>”+retVal+”=>”+str);
9 T9 o& k' v% [8 I }
: v+ k3 X7 ?% P4 X. w+ I1 U 5.4.2.@Aronud
3 s' p7 C$ R) r1 c6 A, l 注解@Around环绕追加功能;
2 R8 U! P% i: S) i+ X' F x# \ 在执行目标对象的方法的前、后追加功能;- J/ N6 ^. ]- x6 i0 N
必须有参数;第一个参数的类型必须为ProceedingJoinPoint;
7 y, E" e4 ~ Z 通过ProceedingJoinPoint的实例的proceed来调用所监控的. w* O0 H' Q* W8 e% K
目标对象的方法7 z7 b, n5 E- k1 M. `
1 定义一个pointcut,通过方法名来作为pointcut的名称来引用" k3 |3 B4 T+ \ ~4 X
(1).@Around(“com.javakc.spring.schemaaop.TestPointcut.t1()”)6 u3 o# J3 v/ n6 y
(2).@Around(“com.javakc.spring.schemaaop.TestPointcut.t2()% w9 Z+ D$ U- J! B5 |4 C9 {
&& args(str)”)
) H- \/ H9 O. c2 ~ 2.直接引用匿名的pointcut* ]! c) \2 C5 P% m2 ~
(1).@Around(“execution(
' n; J: W6 J, r3 P * com.javakc.spring.schemaaop.Api.test1())”)
0 k9 F) y0 W& G. c9 X (2).@Around(“execution(- ]+ t3 L. u9 n& s
* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)1 Q* n! @9 E; J6 E" i
// @Around(“com.javakc.spring.schemaaop.TestPointcut.t2() && args(str)”)
b0 F8 r; f0 h8 n- l$ ? @Around(“execution(* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)
% I8 n9 q" } | public void testAround(ProceedingJoinPoint prj,String str) throws Throwable{
, q+ ?! x) \3 m* u6 U) }% m) X System.out.println(“around1==========before1pointcut==>”+str)
" g1 c! d5 s# y/ k( Q Object obj = prj.proceed();2 N; Y6 M6 ~8 E
System.out.println(“around1==========after1pointcut==>”+str); @4 \4 }6 k/ x6 B
}5 t& H& e5 X5 A) V
5.4.3.@Before
! U8 O0 C! F9 I: S) N 注解@Before在执行目标对象的方法前追加相应的功能
5 R+ P2 f. q: ?: b 1 定义一个pointcut,通过方法名来作为pointcut的名称来引用
9 d2 U, o+ w- w* l6 e( m' ?5 \ (1).@Before(“com.javakc.spring.schemaaop.TestPointcut.t1()”)& }0 f" W* }- e9 ]) H( D
(2).@Before(“com.javakc.spring.schemaaop.TestPointcut.t2() && args(str)”)* u% M' k) l2 b" d4 `
注意args后的名称与参数名相同
3 b( G. l4 x2 Y 2.直接引用匿名的pointcut
7 F5 T8 y' l/ N' I8 Z/ l& ?% o (1).@Before(“execution(* com.javakc.spring.schemaaop.Api.test1())”)) _, F" \$ z1 D2 |* l6 q
(2).@Before(“execution(* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)
" j% r: @9 j5 p/ Y/ C& ?# U 注意args后的名称与参数名相同5 V( ^8 A- ^, b4 O
// @Before(“com.javakc.spring.schemaaop.TestPointcut.t2() && args(str)”); A( e: h C! u( s2 E; Z: p) V; i9 E
@Before(“execution(* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)/ @( g7 P, L7 @( s. |
public void testBeforeParam(String str){
Z4 F! k; Y' ^ System.out.println(“before1=param=>”+str);
; f" x& i& X | }' |4 [% R7 ]! |$ ?, h& T
3 L0 x5 D. C' o6 C* L5 `* M* \& @5 F5.4.4.@After
5 R- u7 {- j% K! H; [- k 注解@After在执行目标对象的方法后追加相应的功能0 W2 _# L/ y0 Z+ d+ [' z5 D. n! d
1 定义一个pointcut,通过方法名来作为pointcut的名称来引用- h! s9 g* E Q( N- n
(1).@After(“com.javakc.spring.schemaaop.TestPointcut.t1()”)
0 J- ^* k/ }4 I k5 K+ f/ F 2.直接引用匿名的pointcut
6 r' i" }& {- T1 f9 Z$ v (1).@After(“execution(* com.javakc.spring.schemaaop.Api.test1())”)
y: _: o( j0 B- _- B3 Q @After(“com.javakc.spring.schemaaop.TestPointcut.t1()”)! H! |9 p) d" x/ ?; q6 [5 Y
public void testAfter(){- q9 A% c$ [% t: \6 f3 g7 c
System.out.println(“after1== >pointcut”);: \6 y5 }+ E0 G+ Z; l. l9 I
}- v: w$ h& ~8 u* x. r. z
5.4.5.@AfterThorwing
3 r/ q: J. I0 ]5 G y- }% j! I
6 K V& ?, |# V& O' r4 N( Q# N! S
9 {( H2 r m) \) _- 描述一下spring中BeanFactory和ApplicationContext的差别" L$ A' \8 I, v+ T; o' l7 P) ]
2 Y: ?. c) H" g/ f" @2 S* b
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”); # k4 Y7 `8 L! p5 w4 ^0 S
- 谈谈spring对DAO的支持
6 |* s ?2 N7 o- _( Z1 v' G" M4 V" a3 ]3 }2 s x
Spring提供的DAO(数据访问对象)支持主要的目的是便于以标准的方式使用不同的数据访问技术。
% a6 Z/ V& _; C 简化 DAO 组件的开发。
- O7 c' E0 { F( z8 CSpring提供了一套抽象DAO类供你扩展。这些抽象类提供了一些方法,用来简化代码开发。3 v; x! g. z; s* X6 X, _) a
IoC 容器的使用,提供了 DAO 组件与业务逻辑组件之间的解耦。所有的 DAO 组件,都由容器负责注入到业务逻辑组件中,其业务组件无须关心 DAO 组件的实现。
4 |% l) a6 @" r" A/ c6 b/ H: { 面向接口编程及 DAO 模式的使用,提高了系统组件之间的解耦,降低了系统重构的成本。" }3 C" ^! u7 L' @0 D
方便的事务管理: Spring的声明式事务管理力度是方法级。2 m+ `2 I( j) N7 e3 L" _8 G+ j
异常包装:Spring能够包装Hibernate异常,把它们从CheckedException变为RuntimeException; 开发者可选择在恰当的层处理数据中不可恢复的异常,从而避免烦琐的 catch/throw 及异常声明。% H+ w2 E( D9 J# i& {. s
% H) I( r( J' S# f2 O" _) @" r) z3 X. |9 d( T; Q0 P
- 谈谈spring对hibernate的支持
, T$ C* r8 a, f+ x9 I' g7 w+ Q+ K/ v9 C) n/ p
在所有的 ORM 框架中, Sping 对 Hibernate 的支持最好。如 SessionFactory 的注入、HibernateTemplate 的简化操作及 DAO 支持等。另外, Spring 还提供了统一的异常体系及声明式事务管理等。
% b; J1 j6 ~7 B 一旦 Hibernate 处于 Spring 的管理下, Hibernate 所需要的基础资源,都由 Spring 提供注入。Hibernate 创建 SessionFactory 必需的 DataSource ,执行持久化必需的 Session 及持久层访问必需的事务控制等,这些原本必须通过代码控制的逻辑,都将由Spring 接管ataSource, SessionFactory, TransactionManager等,都将作为 Spring 容器中的 bean。将这些bean 放在配置文件中管理。7 N6 G" G: }- S& a( A( N( L
1、通用的资源管理: Spring 的 ApplicationContext 能管理 SessionFactory,使得配置值很容易被管理和修改,无须使用Hibernate 的配置文件。详细配置如下:
5 w( g& k: h& z
! O# Q0 ^! ]' u9 P class=“org.apache.commons.dbcp.BasicDataSource”>4 w6 i, ?+ u$ R# S- z) ^. Z5 X: z$ O2 @
" R9 f: p2 G8 S9 a0 k1 E# T
oracle.jdbc.driver.OracleDriver* U; y& {% o: ~' O8 t5 T
; c/ s/ h5 P" P. W0 Q# r
# o6 Y/ Q9 {5 I( Y: F2 J4 [
jdbcracle:thinlocalhost:1521rcl' }: o- m- e. F+ t% w8 y
& U/ w+ a3 f+ `$ G+ _
. k) L) }) }! ]/ ^- p) b9 S0 D8 w javakc2$ _) y X' ^. Z5 F8 t4 n' y% W
+ K/ d9 z) o$ h% D0 f4 _3 W
! I& P- C3 z1 t) C2 {" _; K javakc2
$ G9 q6 A: `- r5 \% i % O9 a* ^+ l; _* ?; L$ z4 D
v$ m [4 i, u
( V& N" N) ?" R3 L$ x; s class=“org.springframework.orm.hibernate3.LocalSessionFactoryBean”>
3 Z( l4 S7 ?! R
* x+ Y5 Z7 I' e/ c3 G) p 7 w6 ]8 n5 a- z& G7 B
1 g) r0 D* N x
com/javakc/spring/h3/UserModel.hbm.xml) C0 T; ]5 [8 _1 S! k
" h2 U7 J- }, |4 X8 g- q6 A
9 M3 A9 G! a8 W5 _. }# o % J8 `, a3 R9 v5 f6 V
5 p9 |5 b ~2 U! m hibernate.dialect=org.hibernate.dialect.OracleDialect
, B+ B6 J; _* J; B2 } 7 m8 E% J- x, e3 }
/ @- F" J+ u: { a3 Q
! ]. A. e- J2 p5 J; y# O. {4 ~
. W( I/ T: k& y' H % w1 b; J$ @0 J" h
' | a. P2 O F D: y& R
如果需要使用容器管理的数据源,则无须提供数据驱动等信息,只需要提供数据源的JNDI 即可。对上文的SessionFactory只需将dataSource的配置替换成 JNDI 数据源,并将原有的 myDataSource Bean 替换成如下所示: class=“org.springframework.jndi.JndiObjectFactoryBean”>0 U; h" ] ~2 ^ S/ e
* z G6 P$ ^( f0 @6 k1 \$ z4 u java:comp/env/jdbc/myds
0 g- ?( y% d0 v. O8 M% x. _1 v
4 j8 v3 ]( c) j0 L4 Z9 _7 E! r$ x1 \ 2、有效的 Session 管理: Dao类继承HibernateDaoSurport后,Spring 提供了 HibernateTemplate,用于持久层访问,该模板类无须显示打开 Session及关闭 Session。它只要获得 SessionFactory 的引用,将可以智能打开 Session,并在持久化访问结束后关闭 Session ,程序开发只需完成持久层逻辑,通用的操作则由HibernateTemplate 完成。 3、统一的事务管理。无论是编程式事务,还是声明式事务, Spring 都提供一致的编程模型,无须烦琐的开始事务、显式提交及回滚。 建议使用声明式事务管理,Spring 的声明式事务以 Spring 的 AOP 为基础。可将事务管理逻辑与代码分离。代码中无须实现任何事务逻辑,程序开发者可以更专注于业务逻辑的实现。声明式事务不与任何事务策略藕合,采用声明式事务可以方便地在全局事务和局部事务之间切换。 Spring声明性事务有两种配置方法,一种是xml配置: 2 |1 S4 W* Z9 o: w4 H" n w' e/ p
( c7 x6 @- {1 l r; A( s
8 o4 [' P" F' `; C * e2 n; q/ O& K0 G! |" } f7 L# G5 L
# [2 D8 p% H- Z2 ~( U3 K2 \) w0 O
$ Q4 Q6 _. p7 ~ " a- }6 T+ l7 R
+ V) `1 r$ S: \
4 V- U I, p: D" B! D$ `
2 P( w/ n# c/ H! R; p; A* h( b6 h6 v) v
6 d/ Q& j0 w1 F
# _$ w9 u+ i/ ]* x7 K , b' p2 S* Z0 G9 K2 x' ?& i
/ i! p( f5 G7 k& A
另一种是通过注解,在需要添加事务的类上注明 @Transactional
0 q6 R5 Q0 O7 w2 B. iSpring2.0之前事务的写法
- s; J) ]0 C* ]1 n! m/ `
3 I! ^) }% b$ E4 R% _) q- }' }+ @6 r7 _5 [% f( {% e
class=”org.springframework.transaction.interceptor.TransactionProxyFactoryBean”/ S% v' O1 @( [3 o# o
* P; `9 D3 q" \* f
abstract=”true”>
; E, N9 i1 u& {. Y" e6 y) S: V) M3 Q; @* b" R
5 ?. g+ [4 n, b3 o
$ ~# _3 w) D& g# r9 a) l! z. Z/ p" ?7 n* C) T1 n; k2 i7 ?
PROPAGATION_REQUIRED,readOnly
+ `4 i- y) U; C; g0 A5 A" v9 _" b) C. T H; q+ o' _, y
PROPAGATION_REQUIRED4 B5 n W7 e4 |; U( H ^
: v+ X6 g3 D4 w; d2 \
* \3 h8 ]. T0 Y+ B8 }5 E7 ^# e5 T- A4 I- j
7 M7 A% Q* F' W$ d
|
" D3 l2 ^! T6 I6 v
2 V2 A1 S8 `8 U- 谈谈Spring对事务的支持+ L7 P% g3 u% I+ S/ T" s
4 U4 I1 J' ~/ h# c6 ~
* |0 Y7 F' {. b3 R/ Z
1、声明式事务管理: 1.流程:由客户端访问—-aop监控—-调用advice来追加事务 2.做法: 2.1 在配置文件的头中引入xmlns:tx 和schema的文件 2.2 2.3 注入数据源
6 u( D2 @2 N+ i" z2 |
( U9 E, k% A! b
0 h, F8 ~8 k: g( c
. F+ T( g) L& u7 i% d2 h) W$ B5 [+ Z2 A0 ~5 A
. v3 X$ L1 ?% g* @& m2.4 由spring实现的事务管理,但需要注入数据源
- y1 A U* t& u* g( i: N( h3 L5 t+ z( ~2 m. S
9 m' D1 Y" Y& g2 f- Z# V
2.5 事务监控所有的方法(事务加强)
8 |% g' X7 o0 u5 ?" l' \/ R9 l/ h' n `
$ a' z/ I7 F! ~* P3 O: u, W
6 U% ]/ p# |0 q3 o+ |8 }
) p: f/ k" x5 e) G: V2.6 定义切入点 ' M4 x: m8 Z$ N" X" N6 l
1 E8 a0 N' w; f3 \ z
9 J: `+ I: p+ F2 t2 I$ y. ^* N0 L$ F5 x8 C) G4 _
5 z, m/ [9 t, \1 Y6 t$ m2、使用注解实现事务管理: 1.注解@Transcational (可以在类上,也可以在方法上) 2.在配置文件中同样需要注入dataSource和spring的事务管理 3.使用注解的方法来追加事务 注解驱动 ! N, R4 a. }) D
Y, e. e w" E. s如何在Spring中使用Hibernate的事务:; s, Z6 p) G7 d6 G
$ J0 _$ m/ I; u/ D" ~' n
3 G, t; Y& i' G0 Z+ m# f
" Q$ Y4 n2 F' L9 u* B. v# _: A
如何在Spring中使用JTA的事务:; c! r F2 {/ v
5 J- z: Z$ `1 G2 ^ |