Spring3 v8 B' Y4 ?& v. T
- 是什么?" |+ g) M% b9 c/ e5 m; J# F% ]: t, _9 J
5 ]" }6 ~# k% m
Spring是基于JEE的轻量级的应用框架 - o$ W- l1 b) W# g( b& |. f$ z
- 有什么?3 ]! j, Q5 ^5 |% A
; i/ ]/ P7 t) O- C) A5 Z7 q5 H; O & c u( }* V2 b5 C4 s2 y! H
每个包的功能: Spring MVC:spring 本身提供的web 框架 WEB:集成其他的web 应用的框架,或者说是对其他web应用框架的支持。如struts,webwork JEE :集成一系列的jee的技术(对JEE技术的支持) DAO:封装了JDBC;(对JDBC的支持) ORM:提供了对ORM工具的集成(支持) AOP :面向切面编成 CORE:spring的核心包,提供bean的工厂和IOC容器 ) S$ C" Q Z* ~8 x. d
- 能干什么?
( k" |# \! [7 r. ?1 M Z0 M6 d
; d5 j7 m! P; E- s# ^
把一系列的jee的技术有效的组合在一起形成以良好的系统 1 \9 e( R3 @- a- B
- 怎么用?
/ o3 _1 P" S: |1 v" W( R! v# v2 H- s' X. n
- 搭建web工程,引入spring的jar包' l$ I$ M. f) ]. o' f/ M0 c' B
- 在web.xml中添加如下配置
7 p2 H" Q m/ D+ a0 Z& I1 V" v
& l3 K& Z: g( f, | * q8 q1 c4 V4 [6 U0 F5 ^; C% O, q
/ A! T1 U4 y" @! Z9 K
contextConfigLocation; o8 w) j8 e3 D# t
classpath*:applicationContext*.xml( v, c; @0 T' e' j3 C
4 G# h2 J' S- J( n1 P& x B 6 Y* P, t4 i2 N. x
struts2( L) e+ ~5 e$ Q5 I# C
5 c2 i! X5 V+ t- f" U! @ org.apache.struts2.dispatcher.FilterDispatcher
+ y, C7 H( J* x$ [1 l 8 A& W0 ~0 e* k: ?+ Z
$ G2 \% {4 p" t
9 j+ |& \: u% r6 c8 d( i0 k& { struts2) f7 S5 F, z9 v: \" S" o
/*
W) Z* {) B D- K. ]9 R
6 |! x) g3 M0 V) i& Q
6 |0 X8 C) ^2 s8 g
( f; x2 B7 q5 }0 m: K: e& T" L org.springframework.web.context.ContextLoaderListener3 D/ l2 j. R4 R$ D+ L4 {) g; x [
( ]* G2 v2 `9 B. @8 k2 j( O$ H - 部署
/ C) \. \4 {2 g. g- D A! K. U
2 U+ ?* @7 ]( ~9 o: r. I % c% Z8 x- t/ V+ s% X5 n3 }
$ n g0 i5 U0 s0 e8 R L
g' q4 s/ j- A- 容器和bean9 g& h$ Q& i! s5 T
Bean :是指受spring的ioc管理的对象称为bean 容器 :(与jee的容器类比) Jee :提供组件的运行环境和管理组件的生命周期(不能单独存在) Spring :提供bean的运行环境和管理bean的生命周期(可以单独存在) # W8 }9 [# A8 ^' g9 m3 X9 P
; k+ s1 G. Y6 a. P' j9 t- DI依赖注入
7 U. R) K- P! Q, F
1. 应用程序依赖spring注入所需要的对象 IOC和DI是对同一种事情的不同描述 2.setter注入: 在配置文件中将接口的实现配置为bean在应用程序中注入bean 例如: 在配置文件中 ) k& |$ w& l' V: }
# `* p3 |- {* a8 t( t
l6 ^# W* R) N. v. V9 X在应用程序中 Public DBDAO dao ; Public void setDao(DBDAO dao){ This.dao = dao; } 3.构造器注入 9 m5 p5 a4 |& z g4 w
4.ref 表示参照其它的bean 在参照的过程中一定要注意死循环 5.自动装配———–〉no 自动装配根据名字来匹配相应的bean 尽量不要去自动装配 6.lookup注入 7.singleton 1.单例模式是整个的jvm中只有一个实例 2.spring的singleton是指在spring的容器中只有一个实例 一个生命周期中只有一个实例 8.DI的优点: 1.程序被动等待,强化面向接口编成 2.切断了对象或组件之间的联系,使程序的结构更加松散,运行和维护更加简单 $ H; N/ k; d& g I+ g
- Aop面向切面编程2 M/ W4 g. u7 A
; d1 l( q8 t8 @ w
1.AOP面向切面编程 一些较好的模式或者是示例—-范式8 b, U' `) g! P
切面:一个切面代表我们所关注的一系列的共同的功能点(模块之间的共同的功能点) 2.AOP的思想: 主动—->被动(追加功能)
" X, _& J5 |+ g U S! l 3.AOP 的概念$ a* E) J7 Z' K. \
1.切面 :我们所关注的功能点 2.连接点 :事件的触发点(方法的执行) 3.通知 :连接点触发时执行的动作(方法) 4.切入点 :一系列的连接点的集合 (连接点的模块化) 5.引入 :扩展的功能 6.目标对象 :包含连接点的对象 7.aop代理 :实现机制 8.织入 :把advice和目标对象连接起来 4.AOP的事件机制
- x' Z* c$ I+ J! J' e1 m0 J 1.通过切面找出一系列共同的功能点 2.找到目标对象(在标准的spring 中 接口的实现类为target) 3.找到切入点 4.确定连接点 5.通知spring AOP,查询xml文件,通过代理找到advice。 6.由aop代理来实现动态织入
~) u2 I2 D, l% T
% t N! \. w. J7 S
4 w) S0 ~! V, l3 z; i, `8 ^
* g9 G' h4 | c$ L0 `! k0 c8 Q2 g- W; ?! @% S' c* @
8 ^& O' a* l& f! C
3 c& F' a% `8 C) D5. AspectJ2 w8 |; c C$ g
5.1.在xml中配置比较烦琐' g6 D d) F/ @- s- i5 y1 Q
所有的入口必须从一个代理(ProxyFactoryBean)开始
; \; y- b+ k! o w7 i2 M) I
1 X) f5 @$ Y& s0 C. Z1 h
8 e5 U, h2 z1 \+ v9 |
; g0 k# V; I% i- S3 ? j" n
% q; F+ ]8 E2 g3 b/ p1 I% X5 n( F7 }, l0 Y5 Z% e1 k4 X! I, @
* k, y# W! e# p & K3 |$ d/ s% m o. b$ {7 H
_0 M/ u, T# Z* |expression=“execution(* com.javakc.aop.MyTarget.t*())”/>
. U! P- L! I# q/ S
' v5 @! ]8 a4 h+ H% q2 T5 F% F
$ v# Y: r& z4 {; t7 `- q' f, G
# v5 ]+ H6 _: x1 \3 ~% E
% @* s' I1 Z7 H9 c! I* |" n, f
% }; m# v8 x! E7 W5.3.使用注解的方法相对简单: |! {6 a" T5 X2 p
@AspectJ的基本语法1 g" z3 C5 q, S y' v7 X1 k% Q
1.@Aspect声明一个切面,将一系列的共同的功能定义成一个切面
! u' L7 \9 |0 r6 F7 D1 g! g 直接在类上定义@Aspect
* ^# R6 }# X( M" P 2.@Pointcut声明切入点
\ u5 g9 D0 K( F3 W8 i$ j6 B% s 2.1、用一个专门的类来定义pointcut,类中的方法名就是该pointcut的名字
" F2 q3 Y! O* J' V! b" O2 v 2.2、可以使用匿名的pointcut4 J1 r9 K2 I) q9 h1 T: i
2.3、执行切点的几种方法
4 P# M( a# u, r. c/ ~ 2.3.1 execute(public * 包结构.*.*.(..)) 可以指定到具体的方法
9 f7 M! F9 H, \( @ 2.3.2 within 指定到包,不能指定到类
8 L( p4 k# E, B within(”com.javakc.spring..*”)+ I& `2 y# G* F- U
2.3.3 this 指定到实现接口的所有的实现类
( S% e( R! ^) J 2.3.4 target 指定具体的实现类
( D+ s! q6 V1 z9 g8 C A 5.4.advice的五种类型的示例
$ L3 n& y" e4 H* L 客户端必须从接口走才能得到监控,实现想要追加的功能& s5 I& \; g) q) }; S
5.4.1.@AfterReturning(pointcut=”” returning=”retVal”)
/ G+ Q3 \7 m: j b% s 追加的方法的参数名字一定要与retrning的名字相同
/ | e5 K% }7 x6 E* S& f1 @ 在注解@AfterReturning中必须加上pointcut和returning两个参数
2 V( d4 w. M5 y1 A, g" l W% g7 n pointcut指所要监控的目标对象的方法
- L% X9 c% ~/ U# N) Z! w 得到目标对象的方法的返回值,来作为参数,进行下一步的处理,参数没有顺序,按参数的名字进行匹配
/ @% w0 M% H# d# y. P, N; | 完成追加的功能
! u1 u* Z( E* b/ W 1 定义一个pointcut,通过方法名来作为pointcut的名称来引用& U3 w, y, I. j5 |/ O9 z' O0 r
(1).@AfterReturning(“com.javakc.spring.schemaaop.TestPointcut.t4()”)# I8 W& r4 o! y9 Q; d" O# g
(2).
7 c* M M5 u5 Y3 R3 C4 g Z 2.直接引用匿名的pointcut" i9 M: o- d8 @7 t, A0 S G
(1).@AfterReturning(“execution(
6 L, j! c) U+ Z6 h% H" O2 | * com.javakc.spring.schemaaop.Api.test4())”)% n/ s. h w3 \+ j
(2).@AfterReturning(pointcut=& Q8 V* u5 h* s1 ]5 O$ Y2 u
“com.javakc.spring.schemaaop.TestPointcut.t4() &&) U* b/ C9 F# e) D
args(str)”, returning=”retVal”)
( E+ X( V3 [$ M5 p7 [3 n* B @AfterReturning (pointcut=”com.javakc.spring.schemaaop.TestPointcut.t4() && args(str)”,returning=”retVal”)7 X6 |" `! {! ~2 _ u* w
public void testAfterReturning(String str,Object retVal){# u [4 k. ^9 b' _9 _; N: F4 ~
System.out.println(“afterReturning1=>”+retVal+”=>”+str); x+ c2 ^5 s ~$ p+ E
}
$ i' K+ `( i0 } 5.4.2.@Aronud
$ `1 d: f2 r9 u( e, ` 注解@Around环绕追加功能;; w: D; b; k- n/ j0 g5 @
在执行目标对象的方法的前、后追加功能;
( F; j' o, m- t/ U0 { 必须有参数;第一个参数的类型必须为ProceedingJoinPoint;
$ Z4 w) s8 _( A1 `0 N 通过ProceedingJoinPoint的实例的proceed来调用所监控的2 I4 x' c$ }- L- I' \
目标对象的方法
: u) X+ m8 j* d3 o0 q8 y 1 定义一个pointcut,通过方法名来作为pointcut的名称来引用
' W2 s" y! y: @ (1).@Around(“com.javakc.spring.schemaaop.TestPointcut.t1()”)2 t) }9 C S M# F. h' R
(2).@Around(“com.javakc.spring.schemaaop.TestPointcut.t2()
0 n5 O! T. Y; H3 Y9 Z && args(str)”)
! g4 z0 N, O S4 ]% u8 b 2.直接引用匿名的pointcut
( s2 T% ^8 I- g- Y (1).@Around(“execution(8 W& N8 k5 }# \
* com.javakc.spring.schemaaop.Api.test1())”)
) v6 d/ L9 m- c8 c) k1 e (2).@Around(“execution(
2 [9 h, F6 @6 q * com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)6 n6 V6 Y1 [8 Z. L, R) p
// @Around(“com.javakc.spring.schemaaop.TestPointcut.t2() && args(str)”)
: z. J3 u( V( x9 m) f5 j% V @Around(“execution(* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)
5 y/ l. S u- L9 r+ ` public void testAround(ProceedingJoinPoint prj,String str) throws Throwable{! ]# m6 x$ n8 S: x/ \9 `
System.out.println(“around1==========before1pointcut==>”+str)
5 `; v6 g2 o( P. K. h. C' p4 W Object obj = prj.proceed();! D+ Y4 s2 H' T6 d6 E
System.out.println(“around1==========after1pointcut==>”+str);# j7 K* |4 r2 f7 c# }, g; w
}% r# y% m6 c J+ y. u3 f
5.4.3.@Before' G4 K8 |; e/ s/ g
注解@Before在执行目标对象的方法前追加相应的功能
/ v2 \+ _# X. g2 F$ w3 F( i* C" u0 d 1 定义一个pointcut,通过方法名来作为pointcut的名称来引用
% j/ @- y) p* B9 F0 e, D/ ]) n (1).@Before(“com.javakc.spring.schemaaop.TestPointcut.t1()”)( i) E* T, H2 a4 Z2 R
(2).@Before(“com.javakc.spring.schemaaop.TestPointcut.t2() && args(str)”)' E+ J% l1 @; [" u1 A, n
注意args后的名称与参数名相同
% x+ \+ `$ ?$ P* w; L 2.直接引用匿名的pointcut
( W4 \& Y7 Z; i- G (1).@Before(“execution(* com.javakc.spring.schemaaop.Api.test1())”)# O" f, G) X6 I! {. I9 `
(2).@Before(“execution(* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)
* g7 N! c; R: f2 C 注意args后的名称与参数名相同
4 Z2 G. r' }, a // @Before(“com.javakc.spring.schemaaop.TestPointcut.t2() && args(str)”)8 D0 M% b9 R I! q; y, C
@Before(“execution(* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”): @: h& q* s/ O7 k g5 O
public void testBeforeParam(String str){% D( i }( f/ U' b' K, b
System.out.println(“before1=param=>”+str);
# U, E' U. k- {! ?" k }
$ J# K( j. |8 P& m7 R / f9 z3 t: c* P' I; j3 }2 y
5.4.4.@After4 ~* [+ F5 b2 l+ L
注解@After在执行目标对象的方法后追加相应的功能1 d+ C7 \' x% y( r0 a- b
1 定义一个pointcut,通过方法名来作为pointcut的名称来引用7 O ^2 J' a7 p
(1).@After(“com.javakc.spring.schemaaop.TestPointcut.t1()”)
+ |% H5 i6 {6 Y" @0 Q 2.直接引用匿名的pointcut6 \+ W& g" |1 q+ }5 ~* c+ N7 I
(1).@After(“execution(* com.javakc.spring.schemaaop.Api.test1())”)% R8 T( \$ g1 t( q
@After(“com.javakc.spring.schemaaop.TestPointcut.t1()”)! _# S j% K) I2 Q
public void testAfter(){$ Y: \; k Q. s/ N2 I4 b& \8 @0 \
System.out.println(“after1== >pointcut”);
- C7 c4 H" F, y: `6 d; Z" f }
& N" l% L, v; E- X( v 5.4.5.@AfterThorwing
7 ^4 X9 `2 T6 G( t & b5 a k8 p3 O, k. j& s
. k$ c* Q1 J; H0 t2 b! W- M1 k, K- 描述一下spring中BeanFactory和ApplicationContext的差别
7 H/ n' J& W+ }$ O8 k: v Z, y- I/ K/ ~' _) _3 l
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”);
/ E4 q9 h: j/ `1 x' R1 c2 z' }- 谈谈spring对DAO的支持
$ Z/ P# J' [: V) l, A% |0 @2 C7 G9 L' k& c, H" d% \
Spring提供的DAO(数据访问对象)支持主要的目的是便于以标准的方式使用不同的数据访问技术。
* A H5 n7 s) u$ ?3 H9 b8 k 简化 DAO 组件的开发。' o" d6 ?6 `3 _# S
Spring提供了一套抽象DAO类供你扩展。这些抽象类提供了一些方法,用来简化代码开发。
% x# w' i% J, Y IoC 容器的使用,提供了 DAO 组件与业务逻辑组件之间的解耦。所有的 DAO 组件,都由容器负责注入到业务逻辑组件中,其业务组件无须关心 DAO 组件的实现。: b3 w9 |) ^2 Q4 D
面向接口编程及 DAO 模式的使用,提高了系统组件之间的解耦,降低了系统重构的成本。
. b5 w- z8 N% i A& ~) { 方便的事务管理: Spring的声明式事务管理力度是方法级。
* q/ }' |& o2 ~7 Z$ e4 Y 异常包装:Spring能够包装Hibernate异常,把它们从CheckedException变为RuntimeException; 开发者可选择在恰当的层处理数据中不可恢复的异常,从而避免烦琐的 catch/throw 及异常声明。0 d2 ^$ l2 c1 x( M1 Q4 O9 ]
3 H8 d: o) K- _
: z' H2 Q( g# D+ R* D- 谈谈spring对hibernate的支持
8 q" t& M- M( h; @" T: b& X3 C7 u0 g
在所有的 ORM 框架中, Sping 对 Hibernate 的支持最好。如 SessionFactory 的注入、HibernateTemplate 的简化操作及 DAO 支持等。另外, Spring 还提供了统一的异常体系及声明式事务管理等。
3 S$ _, m3 D- e1 g0 P# U 一旦 Hibernate 处于 Spring 的管理下, Hibernate 所需要的基础资源,都由 Spring 提供注入。Hibernate 创建 SessionFactory 必需的 DataSource ,执行持久化必需的 Session 及持久层访问必需的事务控制等,这些原本必须通过代码控制的逻辑,都将由Spring 接管 ataSource, SessionFactory, TransactionManager等,都将作为 Spring 容器中的 bean。将这些bean 放在配置文件中管理。3 b J" k9 n$ I7 U: `9 @( D
1、通用的资源管理: Spring 的 ApplicationContext 能管理 SessionFactory,使得配置值很容易被管理和修改,无须使用Hibernate 的配置文件。详细配置如下:
' ~* x) I6 x" t: E8 ^5 v7 p : T4 B, x! E9 J* q
class=“org.apache.commons.dbcp.BasicDataSource”>; ?0 F8 d q6 K6 `
" a2 {& _6 v& {- ~9 X
oracle.jdbc.driver.OracleDriver
* U5 y! n- G; f" u: X2 i' u2 v
9 V g' T" `. c
' z# H( f z' H0 q; i1 n8 P+ c& y jdbc racle:thin localhost:1521 rcl3 S1 r3 ~4 G$ @/ i. p- H
( {/ S4 a$ ]) o- L# E
6 S4 O. T( M* P% K6 ?- d javakc2
$ n# h+ s) j% b' X2 c4 A ) U( s2 u N. @+ Y+ o
5 Q# y6 t x* O! U7 l) d
javakc26 T) I g0 q5 g
2 R; G7 ?0 x) w" O) J ( F! n0 g& Y8 X9 f
4 ~) }' J; g, f0 a! u3 Q7 A class=“org.springframework.orm.hibernate3.LocalSessionFactoryBean”>7 V# a' R& Z) a8 E$ K4 M1 K! s
. |, p" n1 ~' i/ z2 z , }! e' S! o) U# N7 R9 a* S& ]3 ~
7 \; G2 }, @- u0 [/ U% i+ X
com/javakc/spring/h3/UserModel.hbm.xml# _4 D7 D1 D2 q( s" s! q
7 E1 [& w4 f; Z
4 K, d; D2 Y$ g$ ?: _ 1 c3 p' g) Q% V, N$ X
# i; p! l4 [9 q: A1 X" U
hibernate.dialect=org.hibernate.dialect.OracleDialect. U5 k. j0 b c6 h
4 r; F2 p: C9 M* w) o J
! S/ C3 `- d% q& ?6 y4 z$ P
# p1 {( i! k4 H
0 Z5 h) t8 Z% s% F7 h, u 5 k7 | \$ Q$ ~
% H) J# @, ^. ]4 Q9 O
如果需要使用容器管理的数据源,则无须提供数据驱动等信息,只需要提供数据源的JNDI 即可。对上文的SessionFactory只需将dataSource的配置替换成 JNDI 数据源,并将原有的 myDataSource Bean 替换成如下所示: class=“org.springframework.jndi.JndiObjectFactoryBean”>
7 V6 K) f/ r7 \8 @
' \5 I! `6 q, y- ?. } java:comp/env/jdbc/myds
: D1 q0 B3 o5 N ! C7 ?: k1 W5 ?; t. v
2、有效的 Session 管理: Dao类继承HibernateDaoSurport后,Spring 提供了 HibernateTemplate,用于持久层访问,该模板类无须显示打开 Session及关闭 Session。它只要获得 SessionFactory 的引用,将可以智能打开 Session,并在持久化访问结束后关闭 Session ,程序开发只需完成持久层逻辑,通用的操作则由HibernateTemplate 完成。 3、统一的事务管理。无论是编程式事务,还是声明式事务, Spring 都提供一致的编程模型,无须烦琐的开始事务、显式提交及回滚。 建议使用声明式事务管理,Spring 的声明式事务以 Spring 的 AOP 为基础。可将事务管理逻辑与代码分离。代码中无须实现任何事务逻辑,程序开发者可以更专注于业务逻辑的实现。声明式事务不与任何事务策略藕合,采用声明式事务可以方便地在全局事务和局部事务之间切换。 Spring声明性事务有两种配置方法,一种是xml配置: $ ?; u( Y# M) d* p. G+ h4 b
8 n- v _, m& ]( `. @
n. Z& r. c2 n+ k+ h8 ^9 S
0 a, U5 T" g: d" a; p1 b8 M, u
0 t9 ~7 _1 a, U8 |
1 F' k! ^ X( W3 H
3 ] l! k9 h7 g! v
$ g% W( T: U" ^; r8 v 1 `: m) R( L2 E. q5 z6 ], H6 G
6 `% @& t2 X% U+ u/ `7 C* [2 E 4 i: I2 J7 N ], H# }! c
: v- j' |0 @. C3 e 7 g3 W. K: p5 j+ P$ N
: ?# a6 F0 D" F* B3 r% @2 G 另一种是通过注解,在需要添加事务的类上注明 @Transactional 3 W, G9 f% w9 B& X
Spring2.0之前事务的写法# s |0 i: P- U9 c, ^4 u% O( X5 ^& T
7 w2 l( W' K4 }! Q- U5 D
+ F$ L6 q, g% a% b; W8 v class=”org.springframework.transaction.interceptor.TransactionProxyFactoryBean”* v7 h. k% U3 \& d2 m! L
8 h1 P5 ?6 e2 Y1 A6 l+ r abstract=”true”>" d0 Y: P, d- I' r c4 p
( p: J- U+ ?6 @3 z' O% C
6 m" [, _+ i" R* F3 n% e& w
' |" H3 d0 g. F+ ~; ~/ f7 J( l6 W: g
. S0 r. P o T% p3 H
PROPAGATION_REQUIRED,readOnly4 c( Y* q" Y1 j
: }6 u+ u9 Y, h3 x) B
PROPAGATION_REQUIRED
, m6 |+ i4 d: f2 X8 r( k) i% l. n8 T
4 A6 }; g p2 H% b j
+ b! A% }: {0 O7 d" z4 i
1 |! W9 s9 H5 S* b
|
& C! [7 e$ q% i W/ k; V1 Y& ?# S: j. A+ ^& r
- 谈谈Spring对事务的支持# Y& |2 O* K# n; p( h3 `
4 P* C! `; p9 Z
2 N1 W. q6 d1 Q$ M$ I' b
1、声明式事务管理: 1.流程:由客户端访问—-aop监控—-调用advice来追加事务 2.做法: 2.1 在配置文件的头中引入xmlns:tx 和schema的文件 2.2 2.3 注入数据源 Q7 Z* j, Q: y# H0 P! @; D- [8 f
6 d# I9 d) [- o. a2 }
7 i% P4 x E1 D c3 |! b$ c6 y0 I) ^& E% N0 b' E0 [, J8 x F+ [) x; e
) m5 l/ S6 G; l( b2 D0 c
- M2 J: ` x; K X! K, s
2.4 由spring实现的事务管理,但需要注入数据源
( W! o+ w7 Q+ Z# K2 d' E8 s6 b
; ^+ i, h! c; o& {( ]# N9 w4 k7 E4 P' M5 {" V5 H
2.5 事务监控所有的方法(事务加强)
# D+ `- g/ a# K# b; \) C, w4 u$ V# B$ o+ i
2 e& ^% w$ Z# T) p
/ R0 ^2 Z& \5 t9 D$ A1 \
1 e! | O2 H4 F2 E9 G+ ]2.6 定义切入点 3 w# N/ a4 p" b! u8 e+ i* n/ j
7 b7 o- K; u/ V: }* L9 }9 z% s) _$ c$ E1 ]! ~0 X# v
0 ]. H0 \8 F$ f4 A, B! m; E, ?$ p' W
2、使用注解实现事务管理: 1.注解@Transcational (可以在类上,也可以在方法上) 2.在配置文件中同样需要注入dataSource和spring的事务管理 3.使用注解的方法来追加事务 注解驱动
- h# z6 z7 q# L5 x$ _% u5 H8 Y v$ D9 c; }6 ^
如何在Spring中使用Hibernate的事务:5 G5 Y* j9 M, o2 w. R4 S2 w% J
4 }+ t) c2 S, n7 z; z3 ]; n9 e) Z
/ ^0 u: V4 Y& }0 I0 D5 u' y4 \! [ & a3 o1 w( Y3 c
如何在Spring中使用JTA的事务:- O4 E3 V# e1 _& F0 ], z( [
8 l) p8 a" F/ e8 y4 a- S
|