Spring8 A- I9 w' c/ {, C1 f; j. s
- 是什么?
& D" g! o3 {/ {
$ @" W9 ~8 f, x6 t, k# K" v
Spring是基于JEE的轻量级的应用框架
: \( C. K4 C: x3 s& U0 O- 有什么?+ @. k( T! X5 R) }3 a% g: E- w
3 C0 T6 N1 G, r1 r+ n
! ]% H( [3 _* g
每个包的功能: Spring MVC:spring 本身提供的web 框架 WEB:集成其他的web 应用的框架,或者说是对其他web应用框架的支持。如struts,webwork JEE :集成一系列的jee的技术(对JEE技术的支持) DAO:封装了JDBC;(对JDBC的支持) ORM:提供了对ORM工具的集成(支持) AOP :面向切面编成 CORE:spring的核心包,提供bean的工厂和IOC容器 % s# S7 H4 d1 s/ n) Y/ |& C5 @
- 能干什么?
+ g+ X9 y) T( E
) x( D9 `; E: v7 k
把一系列的jee的技术有效的组合在一起形成以良好的系统
2 }/ x$ A$ b t$ F$ l8 g; E- 怎么用?
: x% Y# ?1 M* ^; o+ f3 Q$ e
- X8 G& t! E: @' {& P4 V; _- 搭建web工程,引入spring的jar包, r6 C" t7 p" n& g0 t
- 在web.xml中添加如下配置% s' p9 G" V% w2 E( H/ N4 o* s
# n7 [- I& x" G- d" d / K* _9 f/ E0 [: {
9 i7 K& j! {/ r& ^6 z# ^# c
contextConfigLocation
) N* s; Y+ q3 t* I classpath*:applicationContext*.xml, Y+ u/ _( R3 [ F- d! t, I
4 ?7 P2 u9 R' s/ r, S / _8 O( \! P: B/ s- i
struts2
9 s" @# L3 O8 p4 d" L. P # f) z2 y1 G* Q
org.apache.struts2.dispatcher.FilterDispatcher% j- h: O) q5 ^1 k+ x6 ]
3 W7 G. h0 v9 U- m5 W; E
0 b3 c3 V$ j7 N& V# U* x* x- q: O7 E
. A1 }# h6 C" ?& |1 I# D struts2
( g' r1 Y. k V9 q /** c' C# V2 G' I7 G5 Q; U
$ |: t9 P: v' ^& H2 z3 R
8 O, [7 k$ Q. D5 |/ k, L
6 Q; p; h9 m3 T2 M( _1 n4 t
org.springframework.web.context.ContextLoaderListener
% n* X0 n- q" I2 J& X' v1 ~ ; _7 q0 N, Q! {
- 部署$ |0 y% p- X6 l: G8 e. E, ?
" D# _ b9 I2 C9 W/ K/ w5 m. D
# [% I$ g' }* t: v3 A# o! k4 s( X! \% o
* C8 Z* k% `+ j
- R/ U3 l; `, T# s) j& kBean :是指受spring的ioc管理的对象称为bean 容器 :(与jee的容器类比) Jee :提供组件的运行环境和管理组件的生命周期(不能单独存在) Spring :提供bean的运行环境和管理bean的生命周期(可以单独存在)
$ E, z8 l- T5 G. |; z9 L7 e- s9 Z5 W( p' b6 {2 C8 g: M5 _8 l
- DI依赖注入# @% s2 Z9 z0 I; X) i K9 k5 ?" z
1. 应用程序依赖spring注入所需要的对象 IOC和DI是对同一种事情的不同描述 2.setter注入: 在配置文件中将接口的实现配置为bean在应用程序中注入bean 例如: 在配置文件中 # M# x7 i7 u& s+ ?/ i( S
8 q) W7 O- {! X: |9 j. O! u& R R2 r j
在应用程序中 Public DBDAO dao ; Public void setDao(DBDAO dao){ This.dao = dao; } 3.构造器注入 0 r5 }9 \0 U7 f4 T/ ^; `
4.ref 表示参照其它的bean 在参照的过程中一定要注意死循环 5.自动装配———–〉no 自动装配根据名字来匹配相应的bean 尽量不要去自动装配 6.lookup注入 7.singleton 1.单例模式是整个的jvm中只有一个实例 2.spring的singleton是指在spring的容器中只有一个实例 一个生命周期中只有一个实例 8.DI的优点: 1.程序被动等待,强化面向接口编成 2.切断了对象或组件之间的联系,使程序的结构更加松散,运行和维护更加简单
) ]3 e8 [! _' q" ]. q- Aop面向切面编程
8 S* x- e7 |/ O6 E, k
* w ]4 `( U* d$ ^5 d }
1.AOP面向切面编程 一些较好的模式或者是示例—-范式
1 d3 m. {9 Y& ]0 o+ ^5 y a h 切面:一个切面代表我们所关注的一系列的共同的功能点(模块之间的共同的功能点) 2.AOP的思想: 主动—->被动(追加功能)
) }1 V/ s+ j$ C! U. O6 N 3.AOP 的概念; r$ |+ _; R b% A) X# b9 {- E
1.切面 :我们所关注的功能点 2.连接点 :事件的触发点(方法的执行) 3.通知 :连接点触发时执行的动作(方法) 4.切入点 :一系列的连接点的集合 (连接点的模块化) 5.引入 :扩展的功能 6.目标对象 :包含连接点的对象 7.aop代理 :实现机制 8.织入 :把advice和目标对象连接起来 4.AOP的事件机制
" \8 z7 M) z3 u: w% y& H 1.通过切面找出一系列共同的功能点 2.找到目标对象(在标准的spring 中 接口的实现类为target) 3.找到切入点 4.确定连接点 5.通知spring AOP,查询xml文件,通过代理找到advice。 6.由aop代理来实现动态织入 $ P8 E! I; p5 A4 b( V* w
$ i+ H) h1 J$ q1 l0 O1 ^" Y2 M1 N2 g$ r/ \3 b9 c. [& \
6 J, b( G# i6 `; D7 _9 g( \
3 g1 `4 `. K7 c: i4 V+ f8 b U a) C9 U$ E# k. U
- D1 p! D1 z5 y- U' R
5. AspectJ8 k' B: K/ @& D- v9 Y
5.1.在xml中配置比较烦琐
7 x4 U7 k) ^ h& s- ]! | 所有的入口必须从一个代理(ProxyFactoryBean)开始
7 T6 c6 ^" d5 i1 B. x r
4 B: J$ }9 ?$ t' e
4 P8 d7 n4 }' N5 P. L: X
9 R- N% S4 h( [ a b$ Z" R5 c
6 X0 d, ?) y3 \0 y' F. J
' y2 g8 L! g. m U. u8 T- C4 {
6 U+ i( ^$ r# A( v0 Z
; I8 t3 \/ X' {' r3 ~
& V; q' i9 i+ Z$ _expression=“execution(* com.javakc.aop.MyTarget.t*())”/>
; C6 d# ?7 M: ]2 t" o1 S$ z6 e* q
7 _/ G0 ?6 v/ E: K
3 L+ o& V. y3 m* F% N0 S9 B 4 J4 V. u6 N' a( S5 z. n0 H0 z
. F3 l$ U$ l8 D2 V
- N( f3 J! S6 N" F+ n3 w; \& i5.3.使用注解的方法相对简单# X5 G! m- X& z0 q2 ^
@AspectJ的基本语法) {4 v+ Y. [( W! i6 Y3 H( Q
1.@Aspect声明一个切面,将一系列的共同的功能定义成一个切面
0 m, u* K+ t7 s 直接在类上定义@Aspect
+ d3 g6 Q% P& N8 W 2.@Pointcut声明切入点
- d% f& o! ^7 \, M- Q7 s w 2.1、用一个专门的类来定义pointcut,类中的方法名就是该pointcut的名字, ?0 R% B8 A7 T z4 h/ n; n$ W
2.2、可以使用匿名的pointcut
1 r8 G: U. K; c2 C( | E/ H5 T 2.3、执行切点的几种方法- ~6 z% _/ y# _
2.3.1 execute(public * 包结构.*.*.(..)) 可以指定到具体的方法0 P0 \8 R4 b& \! u! H$ D
2.3.2 within 指定到包,不能指定到类
6 p& N* U* V/ ]- f within(”com.javakc.spring..*”)
7 }& W& ^) m* j2 V; ~/ j: T" @ 2.3.3 this 指定到实现接口的所有的实现类% }! A7 n9 X. l9 U' l* {( m
2.3.4 target 指定具体的实现类
" M+ b3 [# y0 Z: Q& w; W! [8 O! F5 R 5.4.advice的五种类型的示例. z6 p. x2 Y/ g" W. C$ v
客户端必须从接口走才能得到监控,实现想要追加的功能0 k+ g) {9 Q1 t
5.4.1.@AfterReturning(pointcut=”” returning=”retVal”)& ^' E" I; d' i% n9 p* O% H' V& U
追加的方法的参数名字一定要与retrning的名字相同
& t/ W" E1 W( u! D5 P- o( Y 在注解@AfterReturning中必须加上pointcut和returning两个参数& c8 v: i2 N7 [$ B# k8 m6 x- r3 j) u
pointcut指所要监控的目标对象的方法* i4 @" c+ X( x( |0 h6 B. g
得到目标对象的方法的返回值,来作为参数,进行下一步的处理,参数没有顺序,按参数的名字进行匹配
% m' R7 p1 @) o& K) `% Q) E) J9 c! U 完成追加的功能
, u; ?' M; K3 l$ { 1 定义一个pointcut,通过方法名来作为pointcut的名称来引用! N) n* r ~7 W8 \0 a5 A
(1).@AfterReturning(“com.javakc.spring.schemaaop.TestPointcut.t4()”)
7 ]' O4 J% k) F9 j, W! l8 K1 q% Z0 ? (2).
! O: H) e: M: | \3 F 2.直接引用匿名的pointcut
9 S8 y e2 ~7 g" I1 O (1).@AfterReturning(“execution(
7 X( A+ Y' r( i- a2 p2 p * com.javakc.spring.schemaaop.Api.test4())”), @4 W) H, f$ y$ M0 Z' ?( T9 M
(2).@AfterReturning(pointcut=
% Q( [, F' k( S# m: ]3 | “com.javakc.spring.schemaaop.TestPointcut.t4() &&1 p" i( X5 `; G" f: w/ o: F- k
args(str)”, returning=”retVal”)4 L. S- } `0 q3 g
@AfterReturning (pointcut=”com.javakc.spring.schemaaop.TestPointcut.t4() && args(str)”,returning=”retVal”)1 @8 J! A( O9 x# ~8 \/ [! E
public void testAfterReturning(String str,Object retVal){
/ n0 c% @' Z" _- h System.out.println(“afterReturning1=>”+retVal+”=>”+str);! } Y- m6 O/ t( c6 \4 N
}) o0 Z' Z- P8 J; u
5.4.2.@Aronud+ I2 j% ~" J3 S
注解@Around环绕追加功能;
4 `5 L- ~+ @4 s8 a* d- G- ~ 在执行目标对象的方法的前、后追加功能;
- g; E! B& Y1 M( Z$ K! k' c 必须有参数;第一个参数的类型必须为ProceedingJoinPoint;
; r' {- U5 R M5 i9 C/ H- j$ e. r 通过ProceedingJoinPoint的实例的proceed来调用所监控的$ c0 m8 B- v6 b, z( F8 Y
目标对象的方法
7 [8 k2 F8 ~& j F* f, a0 E4 D 1 定义一个pointcut,通过方法名来作为pointcut的名称来引用
" P* R0 B5 Q- L7 Y2 c (1).@Around(“com.javakc.spring.schemaaop.TestPointcut.t1()”)! b# v* K3 C! I1 X7 G
(2).@Around(“com.javakc.spring.schemaaop.TestPointcut.t2()
+ R1 u* ~% t5 |9 G0 p && args(str)”)- T. f# T! v% |; Z. b, N7 H
2.直接引用匿名的pointcut# h) Y& P+ L& w6 R" t3 Q8 @
(1).@Around(“execution(# ?" w3 c, }7 G P0 ^
* com.javakc.spring.schemaaop.Api.test1())”)
' M/ f( `0 C/ A (2).@Around(“execution( [) s* S# W f" ]8 g
* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)
3 B0 F4 a" |& f. C // @Around(“com.javakc.spring.schemaaop.TestPointcut.t2() && args(str)”)
- _, @2 ^0 e! j+ _/ X, N3 w3 c7 L @Around(“execution(* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)
1 y- x9 e Y4 u- A. Z1 D6 R6 p public void testAround(ProceedingJoinPoint prj,String str) throws Throwable{( Q* k9 [: |+ b6 e& p% {; S
System.out.println(“around1==========before1pointcut==>”+str)
. m/ X: e) W, }+ R: q2 I+ B r Object obj = prj.proceed();* |9 a+ A( m8 H" U- X& g0 L
System.out.println(“around1==========after1pointcut==>”+str);
! k* Q( n0 A0 n1 A. x }+ D- W1 v4 ^4 D5 t
5.4.3.@Before
) r) Q" M2 y$ g9 n% x6 t 注解@Before在执行目标对象的方法前追加相应的功能( w' M4 B% R! d7 j: S
1 定义一个pointcut,通过方法名来作为pointcut的名称来引用7 G0 j* U! O0 _; w. L8 H
(1).@Before(“com.javakc.spring.schemaaop.TestPointcut.t1()”). g* d* `) F% e( @# N, V5 z/ K
(2).@Before(“com.javakc.spring.schemaaop.TestPointcut.t2() && args(str)”)
5 o8 o7 M+ I6 u1 J 注意args后的名称与参数名相同
$ B( f) w/ b9 W 2.直接引用匿名的pointcut7 x5 R+ n! k% }9 m0 B0 T1 G9 J
(1).@Before(“execution(* com.javakc.spring.schemaaop.Api.test1())”)
, ^7 r% `/ C6 j9 n5 w$ U (2).@Before(“execution(* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”), j' D# o! j0 Z
注意args后的名称与参数名相同
. \4 [/ k2 Q/ P1 \7 E \ // @Before(“com.javakc.spring.schemaaop.TestPointcut.t2() && args(str)”)
8 H) K! j7 c8 z @Before(“execution(* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)
9 X- y( v5 K+ C4 c6 _ public void testBeforeParam(String str){
' D, W4 s' r2 p5 Z" ^+ O! t4 g System.out.println(“before1=param=>”+str);
5 r: L$ Q8 Q4 M. X }6 d3 {# f3 [2 O0 d) z- B
* M: W$ y% {3 W# `- s
5.4.4.@After
, N& g) K2 J" \8 H5 F 注解@After在执行目标对象的方法后追加相应的功能
! ~6 l1 @# D- a4 L 1 定义一个pointcut,通过方法名来作为pointcut的名称来引用
! J/ V m9 @* d! h (1).@After(“com.javakc.spring.schemaaop.TestPointcut.t1()”)
1 J- Y$ M+ {" K 2.直接引用匿名的pointcut: L* C$ v y" s
(1).@After(“execution(* com.javakc.spring.schemaaop.Api.test1())”)
! c" i5 n% }6 F5 `, i" L( z9 a- d @After(“com.javakc.spring.schemaaop.TestPointcut.t1()”)
- Q8 s7 t5 s, N& E' F" F public void testAfter(){* Z! l0 \; w/ `$ i9 K
System.out.println(“after1== >pointcut”);& t) K, `( V' A* @
}
# f; O% z! y5 l6 }0 q& c 5.4.5.@AfterThorwing8 t/ e3 o2 Q3 B# P& F$ H- X
. C7 B1 I# t. X! T' O, [+ Q; g9 k" L" n [4 E
- 描述一下spring中BeanFactory和ApplicationContext的差别# o* d+ u& r0 X) _" ]6 y; d* E0 F
' q0 a% y( ]9 Z7 U% V4 K
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”);
+ b5 l4 ?; D# l& w+ x5 N- 谈谈spring对DAO的支持* n* ]8 V8 f$ _: }+ d& j
5 O5 n5 H: C1 n' j3 |
Spring提供的DAO(数据访问对象)支持主要的目的是便于以标准的方式使用不同的数据访问技术。) B7 U+ n; }; P V$ j$ @ w
简化 DAO 组件的开发。
* f- h9 x$ y8 _Spring提供了一套抽象DAO类供你扩展。这些抽象类提供了一些方法,用来简化代码开发。$ u2 B0 S4 Y: B# |% b
IoC 容器的使用,提供了 DAO 组件与业务逻辑组件之间的解耦。所有的 DAO 组件,都由容器负责注入到业务逻辑组件中,其业务组件无须关心 DAO 组件的实现。
6 E5 h3 o2 }0 p/ | 面向接口编程及 DAO 模式的使用,提高了系统组件之间的解耦,降低了系统重构的成本。
3 p. M6 K' I) b2 i' N7 i8 ^ 方便的事务管理: Spring的声明式事务管理力度是方法级。
$ |2 i5 a4 l% ^" ^4 Z 异常包装:Spring能够包装Hibernate异常,把它们从CheckedException变为RuntimeException; 开发者可选择在恰当的层处理数据中不可恢复的异常,从而避免烦琐的 catch/throw 及异常声明。: D3 `* O( I6 Q5 M+ M* T
5 l( I& C. u% ^: L6 D0 J* c
' \% U# N0 Z8 z. L8 z( \$ k
- 谈谈spring对hibernate的支持
7 [/ D7 x* V8 }3 j* Q5 {, F4 C. {2 `/ G( i2 T7 d
在所有的 ORM 框架中, Sping 对 Hibernate 的支持最好。如 SessionFactory 的注入、HibernateTemplate 的简化操作及 DAO 支持等。另外, Spring 还提供了统一的异常体系及声明式事务管理等。! b/ e- f- h3 V1 j0 X' h! m. t
一旦 Hibernate 处于 Spring 的管理下, Hibernate 所需要的基础资源,都由 Spring 提供注入。Hibernate 创建 SessionFactory 必需的 DataSource ,执行持久化必需的 Session 及持久层访问必需的事务控制等,这些原本必须通过代码控制的逻辑,都将由Spring 接管 ataSource, SessionFactory, TransactionManager等,都将作为 Spring 容器中的 bean。将这些bean 放在配置文件中管理。
/ C2 D0 A5 X- F! V 1、通用的资源管理: Spring 的 ApplicationContext 能管理 SessionFactory,使得配置值很容易被管理和修改,无须使用Hibernate 的配置文件。详细配置如下:: c1 h/ C- a( B' L+ ?2 X
! {0 { Q6 J& Q( a& P) U U
class=“org.apache.commons.dbcp.BasicDataSource”>2 K3 N, c7 f' @' j8 M& Z
$ D7 _. J* b* H oracle.jdbc.driver.OracleDriver" l, p/ x# E) e! M5 a
; g. n* O* C' H/ n) k0 X
- M) b- f: a. q
jdbc racle:thin localhost:1521 rcl
* l3 ]% L* W) S& I: f" t
- t6 {: `1 U9 T" S4 Y $ E( |2 W0 O9 H" S
javakc2$ J( Z2 m/ F) q3 |* M! G
5 v1 J+ V' |+ V
" |3 I% ]/ i- @ X- Q; f
javakc2
( f+ H- X# G5 G5 a" b ! L( B Z9 n" h+ m
" L$ p+ Z2 r7 P6 V x# [- B3 h2 H5 L
9 I4 D" p/ l9 h$ O" p; J$ n j+ [
class=“org.springframework.orm.hibernate3.LocalSessionFactoryBean”>
3 C( d G* T5 ^& h+ T/ t
# ~( Y9 z* X, ]5 c
, } b. C: u# |6 x7 F
4 x2 N/ M0 a2 l, v! W& N* | com/javakc/spring/h3/UserModel.hbm.xml
* g, M! T9 T) x v& ^ ; U8 Y- W3 `) I# ^6 v/ d" {& z( r
1 n8 H# \6 S0 n ' q* T& _( K- w* S9 Y' l
) v/ e( u+ m$ l/ W( R8 X hibernate.dialect=org.hibernate.dialect.OracleDialect
$ R+ D$ K( g" x* A/ A! i9 A
U. E& }1 X; s, p. D
8 G, o6 V& E4 z* U" r% y- h5 Z
7 M. f" |; E d( B/ o9 X) L1 ^
6 y# Y* T: V( o2 R3 U
) a" G9 s4 z3 s* h 5 w1 F# R4 Q, q9 S( |. N7 o
如果需要使用容器管理的数据源,则无须提供数据驱动等信息,只需要提供数据源的JNDI 即可。对上文的SessionFactory只需将dataSource的配置替换成 JNDI 数据源,并将原有的 myDataSource Bean 替换成如下所示: class=“org.springframework.jndi.JndiObjectFactoryBean”>
5 X3 k( b$ Z, w! V 7 t8 k `1 M, ?7 |5 Q3 F8 M
java:comp/env/jdbc/myds" N, v+ |( l; c7 A
( \3 I$ D2 E# O# [0 ?" P 2、有效的 Session 管理: Dao类继承HibernateDaoSurport后,Spring 提供了 HibernateTemplate,用于持久层访问,该模板类无须显示打开 Session及关闭 Session。它只要获得 SessionFactory 的引用,将可以智能打开 Session,并在持久化访问结束后关闭 Session ,程序开发只需完成持久层逻辑,通用的操作则由HibernateTemplate 完成。 3、统一的事务管理。无论是编程式事务,还是声明式事务, Spring 都提供一致的编程模型,无须烦琐的开始事务、显式提交及回滚。 建议使用声明式事务管理,Spring 的声明式事务以 Spring 的 AOP 为基础。可将事务管理逻辑与代码分离。代码中无须实现任何事务逻辑,程序开发者可以更专注于业务逻辑的实现。声明式事务不与任何事务策略藕合,采用声明式事务可以方便地在全局事务和局部事务之间切换。 Spring声明性事务有两种配置方法,一种是xml配置: " n. x3 @3 c, a, u
0 R( T$ r: ^( Y) P
% W8 q' F$ Z9 C S
9 [% U) C: M) a& }
5 K% v3 p, c9 y$ Q : a) W& G% N! v# y- ?$ b8 t
' E1 o# v* z1 w% `2 [
' I+ @7 ~1 h/ J' }# Y * D% k4 G7 F. M! t E$ C# e
0 [2 j& f0 [7 C
# ? P8 k0 x& @# a/ I % V9 ^" l& V% W+ {
7 i( h/ z2 A! D! L6 Z- A: ]7 l8 x, i
) z" w9 B0 ?2 S7 G/ T 另一种是通过注解,在需要添加事务的类上注明 @Transactional
3 o2 E) |" U( r/ c+ r1 m2 ~" dSpring2.0之前事务的写法
3 N x6 J, R+ |. O& t7 q% B: c+ v) n9 }+ h+ ~2 P
7 u7 ?+ w9 h5 E class=”org.springframework.transaction.interceptor.TransactionProxyFactoryBean”
5 e7 j4 y( f/ V7 h" B! k$ p& ~
, L7 S3 }0 R( m z+ M abstract=”true”>
# S5 i: E8 ^; V, @4 z' s+ }5 m% c1 L# f, Y4 D
, T7 M4 S' ~+ W& \0 z0 @2 u, d
; K$ C# T6 V; W1 q5 e0 B$ R PROPAGATION_REQUIRED,readOnly
2 r" Y6 l9 m; q' z e) @' A/ {! |7 M) |/ t3 q. \& M& r" E/ b
PROPAGATION_REQUIRED
+ \4 m. ^8 _$ ?7 R" p0 N# Y! K2 u) H! D- _" x7 }, N
. o( W9 v: [! H4 R- z$ x) b: Q
$ P& {" H+ h n! |) u4 J" D3 l7 b$ [3 i/ ^7 Z4 N
| 2 _0 R3 i* f# M- q5 D
5 B+ ~/ Y. q F- K
- 谈谈Spring对事务的支持
& v* g* x( x7 @ M/ V& Q, Y- w+ H( V& V* k' G% ?
9 ~; q4 T9 V4 X+ O( B+ o& T/ y1、声明式事务管理:
1.流程:由客户端访问—-aop监控—-调用advice来追加事务 2.做法: 2.1 在配置文件的头中引入xmlns:tx 和schema的文件 2.2 2.3 注入数据源 : H5 k$ Z4 z$ s# @( {
P( S# p- i1 D! i
; ? t' r, }2 x0 @ e( v6 \9 {( e
/ r9 m0 u$ _% T% V! p `& w! b' B7 H! d! ^' Y8 o% A$ L4 Q! J$ z
2.4 由spring实现的事务管理,但需要注入数据源 / ?9 _$ k7 v+ v2 Q
; G+ K& Q% X+ z8 @0 c) }% j0 S1 S* z( Q( @. }
2.5 事务监控所有的方法(事务加强) " T. e9 T. X2 Y1 f1 q( C
5 K# q6 d0 Q" X# h9 }. Y0 r! T4 L7 H( w7 n/ {$ y8 }& G/ U+ Q) {
" y/ k3 F& b4 y3 N5 v+ I: K
3 L8 x3 K( m( ^6 A: P# ~
2.6 定义切入点
% M' }/ ]; i- J! }8 c( ^, }; C! t, R8 W+ |- Y8 a- d
. P0 {* t8 K) a) {. K4 _* h0 Y( p6 v }& L0 j# E. h
) b( r R( o; J; c2 `2、使用注解实现事务管理: 1.注解@Transcational (可以在类上,也可以在方法上) 2.在配置文件中同样需要注入dataSource和spring的事务管理 3.使用注解的方法来追加事务 注解驱动 4 ^4 e( b0 G3 b5 c, _
: s0 C) O% @' [8 R; @
如何在Spring中使用Hibernate的事务:6 L+ Y S' O- R& r* P" t
& d" y+ G4 L0 w; O, M9 m
6 v" x( V1 n2 c. i, {. n $ T" m- f( t, g) W! a
如何在Spring中使用JTA的事务:
& U: G$ V0 u) [
! n2 H( ^ ]# `0 ^( M/ l |