Spring+ n% K& _6 k/ |* {3 o- n& `3 E( t
- 是什么?
- |1 j$ @6 E& y2 d$ f0 I- b. _- _! R& h4 T5 ^ K/ G
Spring是基于JEE的轻量级的应用框架
3 E& t4 l" h) J- s, ~: I% C- 有什么?: C' r0 P/ R9 ]8 ?
- r# Q' i0 y, J9 Q9 O
4 F$ J, l* H& N5 J! G
每个包的功能: Spring MVC:spring 本身提供的web 框架 WEB:集成其他的web 应用的框架,或者说是对其他web应用框架的支持。如struts,webwork JEE :集成一系列的jee的技术(对JEE技术的支持) DAO:封装了JDBC;(对JDBC的支持) ORM:提供了对ORM工具的集成(支持) AOP :面向切面编成 CORE:spring的核心包,提供bean的工厂和IOC容器
{* ?* Y3 d$ `. p& @9 a" Y3 n- 能干什么?- M8 J. ^9 q. x5 V F! ^
# r8 V, |5 J% n# u7 B& `
把一系列的jee的技术有效的组合在一起形成以良好的系统
. e% r% j8 Y* @- 怎么用?
; \; c% I) b9 X# D- U3 \8 [1 j, ~2 }6 |6 ^" V+ i
- 搭建web工程,引入spring的jar包
0 p2 z7 w r. { V - 在web.xml中添加如下配置( v8 k; O( U# ^* o
9 J6 h& Q3 r Y k( h " I/ u) B. B$ T' E% W+ q
9 f. q; M: O; N, [! W! @. ^
contextConfigLocation
* q' S9 f% s/ q% w classpath*:applicationContext*.xml9 }# @( U4 e% u5 k6 f1 u- @8 _2 m
% G! B7 t3 x5 i4 R/ ~- i
) ^" i2 R) T0 X% w: {* C
struts20 `' W4 Y5 c$ \# @3 E) A
7 ?2 C( m3 \4 _4 |
org.apache.struts2.dispatcher.FilterDispatcher
6 ^' N) v" U# u" m
y, d( P" _3 e6 d+ {9 [& M" Z* j4 p
% A- s' ?' o) e. f
; p; I& y5 ~4 Y+ @7 R struts2
2 K; z ?" L3 k6 h# v& ^% c2 q- c /*
2 s: p7 a U4 B f% a
! V1 r9 V; I+ g; K& P
7 ]: r6 j3 \0 y
( B2 ]+ ?( }- E' `+ _. z0 D* \ org.springframework.web.context.ContextLoaderListener
& e: j8 J4 t: q; v7 x. w. m # S9 C' b" r4 ^) z( j
- 部署
, \# J% \; h) c& r- W3 t- N5 W* [' O- T N1 K9 g
: T5 _4 v: K$ r
* S' A s/ w% ?- N1 T
% W! E/ n: f- Z' {0 f- 容器和bean
5 }4 p9 B' s! ^0 N! Z6 w* X2 d
Bean :是指受spring的ioc管理的对象称为bean 容器 :(与jee的容器类比) Jee :提供组件的运行环境和管理组件的生命周期(不能单独存在) Spring :提供bean的运行环境和管理bean的生命周期(可以单独存在)
0 K) F7 ]: s; F; ?5 A {7 S# u. j8 b" Z. ]9 U0 Y
- DI依赖注入
2 {, v% r7 X3 n- {4 T+ j. ?9 r4 a1 j
1. 应用程序依赖spring注入所需要的对象 IOC和DI是对同一种事情的不同描述 2.setter注入: 在配置文件中将接口的实现配置为bean在应用程序中注入bean 例如: 在配置文件中
. i1 f' a! A) v- i, E7 G0 c, j1 i, y$ H! F5 [
' G9 ]/ u l% T. J$ ^在应用程序中 Public DBDAO dao ; Public void setDao(DBDAO dao){ This.dao = dao; } 3.构造器注入
- L0 Y8 M5 T. i6 b( }) O, A$ |4.ref 表示参照其它的bean 在参照的过程中一定要注意死循环 5.自动装配———–〉no 自动装配根据名字来匹配相应的bean 尽量不要去自动装配 6.lookup注入 7.singleton 1.单例模式是整个的jvm中只有一个实例 2.spring的singleton是指在spring的容器中只有一个实例 一个生命周期中只有一个实例 8.DI的优点: 1.程序被动等待,强化面向接口编成 2.切断了对象或组件之间的联系,使程序的结构更加松散,运行和维护更加简单 5 X( }. Y- T9 F) j8 I% b
- Aop面向切面编程
6 X% E$ E* y4 @! w! z0 R! f
' c% v1 {& |0 v/ O8 e
1.AOP面向切面编程 一些较好的模式或者是示例—-范式# a* V8 I# c) F
切面:一个切面代表我们所关注的一系列的共同的功能点(模块之间的共同的功能点) 2.AOP的思想: 主动—->被动(追加功能)% |) S9 x& q a' y
3.AOP 的概念
+ r# }$ S- i, O: ~# _ 1.切面 :我们所关注的功能点 2.连接点 :事件的触发点(方法的执行) 3.通知 :连接点触发时执行的动作(方法) 4.切入点 :一系列的连接点的集合 (连接点的模块化) 5.引入 :扩展的功能 6.目标对象 :包含连接点的对象 7.aop代理 :实现机制 8.织入 :把advice和目标对象连接起来 4.AOP的事件机制
! D; N# l& E$ d1 G6 Y. Q5 J 1.通过切面找出一系列共同的功能点 2.找到目标对象(在标准的spring 中 接口的实现类为target) 3.找到切入点 4.确定连接点 5.通知spring AOP,查询xml文件,通过代理找到advice。 6.由aop代理来实现动态织入
! V6 I4 r# @- U. M. k9 I$ X
) i! ?5 B$ v% Z" ^) d
2 \; K. Y8 v1 m9 T
3 H3 |# C1 y4 b% Q0 f9 N/ i# k& \4 C( L0 t& L* v
6 O; p$ \' Y# {2 d. Q+ O* C
0 i" {( f, k; _4 h5. AspectJ
$ T3 ] @3 O' U% e 5.1.在xml中配置比较烦琐6 ^; G5 ]& F, c, c( ]
所有的入口必须从一个代理(ProxyFactoryBean)开始
. {) _ g0 C @+ w 0 F" b' Q. m9 c4 T! {: n6 r
7 R/ T4 H! x2 ?9 o) g
. _$ V- x8 t8 n
. n" H6 f5 } l m. H# D* E
1 E# c. o$ N4 w
$ @# j0 K# }+ C$ o7 ]9 H
( ?6 {# E# t! B3 R
: m5 p- a) E# {. gexpression=“execution(* com.javakc.aop.MyTarget.t*())”/>0 K( Q$ p- q4 O/ ^
7 {# j' t" c4 u+ A' n; P( N
) b# q! `% Q( W7 {) Z
3 C0 c' w V4 l+ [' j) k
! I: g' ]. {% _9 h* {4 a; M6 y/ g6 ~
5.3.使用注解的方法相对简单8 A0 S+ o3 e M6 |; V/ i. s' E
@AspectJ的基本语法
) N4 L( n5 H% s% e# C7 X+ L& J 1.@Aspect声明一个切面,将一系列的共同的功能定义成一个切面
6 j0 i. c7 V; g4 {3 m& q. } 直接在类上定义@Aspect
5 ^: M/ d8 x( U0 C! a 2.@Pointcut声明切入点
+ y( J0 z1 P1 {* [4 w 2.1、用一个专门的类来定义pointcut,类中的方法名就是该pointcut的名字% h" c9 W. `7 ^8 r
2.2、可以使用匿名的pointcut
1 }4 k' Q* ^$ s3 H' v+ u9 K4 r) N 2.3、执行切点的几种方法; q5 v1 ^4 Y! F) S T ?- K
2.3.1 execute(public * 包结构.*.*.(..)) 可以指定到具体的方法2 J y& u: i! G$ v0 H
2.3.2 within 指定到包,不能指定到类
9 _. \# W9 @8 P8 R8 ~ within(”com.javakc.spring..*”)
1 q) Q5 k* Q1 y0 Q% e 2.3.3 this 指定到实现接口的所有的实现类
) k" V% N* H! u4 j1 n1 Y 2.3.4 target 指定具体的实现类" D. u' o6 Q. I. b0 v( p1 U3 p
5.4.advice的五种类型的示例9 I8 v8 n3 w7 {; z8 {5 f
客户端必须从接口走才能得到监控,实现想要追加的功能
& u( y6 P/ f' z2 A4 [$ a, n C 5.4.1.@AfterReturning(pointcut=”” returning=”retVal”)9 B- `: O' `! w4 I
追加的方法的参数名字一定要与retrning的名字相同
+ F7 E: W1 H) J 在注解@AfterReturning中必须加上pointcut和returning两个参数# a) x o/ j x4 \
pointcut指所要监控的目标对象的方法
: H1 R& J3 D) I( x/ E0 w 得到目标对象的方法的返回值,来作为参数,进行下一步的处理,参数没有顺序,按参数的名字进行匹配5 }% o+ H) f, B% n
完成追加的功能9 f$ K$ l& K' e
1 定义一个pointcut,通过方法名来作为pointcut的名称来引用
1 a! i# G8 N6 j+ d# N# y (1).@AfterReturning(“com.javakc.spring.schemaaop.TestPointcut.t4()”)
: N0 p o; O" C+ h3 L5 q (2)., _( V* R( w7 h P& C" M
2.直接引用匿名的pointcut% J, ^, t- x! g7 |6 n" M
(1).@AfterReturning(“execution(" D& u8 D' d E2 `. I1 A/ y
* com.javakc.spring.schemaaop.Api.test4())”). e9 U; z8 `- R0 k- }; Y
(2).@AfterReturning(pointcut=
& P+ I( w1 |. W A3 Y) t9 i “com.javakc.spring.schemaaop.TestPointcut.t4() &&3 o; j! W; p0 O, e' J
args(str)”, returning=”retVal”)+ I7 D- f! I' `# U( t6 k/ Z
@AfterReturning (pointcut=”com.javakc.spring.schemaaop.TestPointcut.t4() && args(str)”,returning=”retVal”)
" ]& z/ ^! M: [* e/ ^, a) u public void testAfterReturning(String str,Object retVal){
+ B# X' w; O9 _' L" b" @ System.out.println(“afterReturning1=>”+retVal+”=>”+str);
4 `% N& G' S7 V }
/ G, e5 t! C- I: H( d- u& d6 S+ c- C 5.4.2.@Aronud
: O% A* ^9 ]/ {9 B, i 注解@Around环绕追加功能;/ f' [. {+ o$ b( p
在执行目标对象的方法的前、后追加功能;4 i4 u3 o$ V5 [" w, o
必须有参数;第一个参数的类型必须为ProceedingJoinPoint;# y/ X2 `& o0 }8 M5 P
通过ProceedingJoinPoint的实例的proceed来调用所监控的
: ]6 q+ G2 L+ U) O+ `" j% p8 V% N 目标对象的方法
9 o3 G. A, k& P 1 定义一个pointcut,通过方法名来作为pointcut的名称来引用& h7 j6 x. x. r2 S& j
(1).@Around(“com.javakc.spring.schemaaop.TestPointcut.t1()”)2 ]0 \9 T- _* x
(2).@Around(“com.javakc.spring.schemaaop.TestPointcut.t2()
) ?$ @3 g# r( H }6 Z && args(str)”)5 u, Y( r( n6 L
2.直接引用匿名的pointcut
7 m1 @- p c( A" J1 a/ t" \ (1).@Around(“execution(
% m+ Y, g& e( F- P8 r% Q * com.javakc.spring.schemaaop.Api.test1())”)2 V3 ]5 U3 R2 V% I
(2).@Around(“execution(
& Q1 q b, E/ s' Z' V$ W" s/ W9 U7 ] * com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)
" c3 L0 r) g: b% V // @Around(“com.javakc.spring.schemaaop.TestPointcut.t2() && args(str)”)1 L# U4 C" G8 K, Q3 M, p/ k
@Around(“execution(* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)$ p4 u" h+ W5 l9 e* E
public void testAround(ProceedingJoinPoint prj,String str) throws Throwable{
9 k/ u" s5 G9 E. ]& W! g System.out.println(“around1==========before1pointcut==>”+str)- S' _9 G: F5 a6 u
Object obj = prj.proceed();
, ^5 w5 _% f2 k$ l System.out.println(“around1==========after1pointcut==>”+str);
. l0 l0 Z- Z8 Z' ^7 W( K- L }
0 f. S- c i* D4 v5 K 5.4.3.@Before
; P' N3 _6 x3 D5 b; r* N- P 注解@Before在执行目标对象的方法前追加相应的功能. W; _6 c" `8 T ^2 X) `. f
1 定义一个pointcut,通过方法名来作为pointcut的名称来引用
) |$ [# d8 P. q+ y8 d; E (1).@Before(“com.javakc.spring.schemaaop.TestPointcut.t1()”)
; A) ~' X$ [4 @! U% y. z2 O (2).@Before(“com.javakc.spring.schemaaop.TestPointcut.t2() && args(str)”)% _0 R# b6 ~5 A& J% F5 d
注意args后的名称与参数名相同; j; s/ K) M5 V
2.直接引用匿名的pointcut% b9 n. F: Q ~. z7 A
(1).@Before(“execution(* com.javakc.spring.schemaaop.Api.test1())”)
# V! s7 z, t' P7 U X( w: J: E (2).@Before(“execution(* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)2 Z6 I# f& ~3 u- H X$ _8 X
注意args后的名称与参数名相同7 I) |! B4 } C0 f9 F% C; \6 a) g
// @Before(“com.javakc.spring.schemaaop.TestPointcut.t2() && args(str)”)
1 T2 b: d7 L+ b! n @Before(“execution(* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)9 T" E( Z- x; H2 c0 P3 _
public void testBeforeParam(String str){
- w& C3 N' K; S5 P ]$ f5 w System.out.println(“before1=param=>”+str);0 Y& C) H! T# g4 r# b0 x
}
5 g# @0 G7 [/ n* X8 y
" a" {2 _2 F+ E) x0 L* `5.4.4.@After
6 i. N) ?& B9 i' k+ x% g 注解@After在执行目标对象的方法后追加相应的功能. y0 h/ E: B, m/ ?' }+ E. z" ^
1 定义一个pointcut,通过方法名来作为pointcut的名称来引用
' z3 J! N, @( D5 Y (1).@After(“com.javakc.spring.schemaaop.TestPointcut.t1()”)/ B4 K" p9 u; l; {
2.直接引用匿名的pointcut
; l. u. Y$ @0 `+ } (1).@After(“execution(* com.javakc.spring.schemaaop.Api.test1())”)
: X) O. A, m/ r5 \ @After(“com.javakc.spring.schemaaop.TestPointcut.t1()”)
+ S2 v* u" L' j: J$ J* j$ U public void testAfter(){
2 J% Z9 D) q# _4 N2 y5 z System.out.println(“after1== >pointcut”);
& J9 n- K- R$ n$ O( A }1 C: E9 b) a; ?! u+ I _& A
5.4.5.@AfterThorwing
; q1 `3 @! L# E+ g1 p1 C ! }; ^- T' I9 Z1 K- o0 j+ h5 f
+ ] i6 Q& q7 i. J8 t- 描述一下spring中BeanFactory和ApplicationContext的差别
5 b! N* I S7 A+ O7 W; I# } c$ j9 f; w$ ^5 W1 }
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”);
/ A0 k# C B/ _, `/ U& v- 谈谈spring对DAO的支持
k: Z; s" v4 `( D
" ]9 ^, |) u- T
Spring提供的DAO(数据访问对象)支持主要的目的是便于以标准的方式使用不同的数据访问技术。, `; w1 v& W- L3 a8 r1 I7 m
简化 DAO 组件的开发。
) d; B7 u7 s" w' Q! `! JSpring提供了一套抽象DAO类供你扩展。这些抽象类提供了一些方法,用来简化代码开发。( B+ ?9 A- x5 h U4 y
IoC 容器的使用,提供了 DAO 组件与业务逻辑组件之间的解耦。所有的 DAO 组件,都由容器负责注入到业务逻辑组件中,其业务组件无须关心 DAO 组件的实现。: k8 ~" k) @& x' P! U
面向接口编程及 DAO 模式的使用,提高了系统组件之间的解耦,降低了系统重构的成本。
2 u+ W b1 ~- d 方便的事务管理: Spring的声明式事务管理力度是方法级。
1 s' S6 T) u* V* e$ E( l 异常包装:Spring能够包装Hibernate异常,把它们从CheckedException变为RuntimeException; 开发者可选择在恰当的层处理数据中不可恢复的异常,从而避免烦琐的 catch/throw 及异常声明。' H2 W x1 |- p9 A9 o# K- U+ b) C* x
( c1 ?0 z% H, Y% e: D" S5 U) {6 B, D
- 谈谈spring对hibernate的支持6 w; N8 d! E; \ ^
$ ~3 Z5 x& \: n+ K( V. v: Q
在所有的 ORM 框架中, Sping 对 Hibernate 的支持最好。如 SessionFactory 的注入、HibernateTemplate 的简化操作及 DAO 支持等。另外, Spring 还提供了统一的异常体系及声明式事务管理等。: |: O, Y3 h9 p; M; G$ o1 n. l
一旦 Hibernate 处于 Spring 的管理下, Hibernate 所需要的基础资源,都由 Spring 提供注入。Hibernate 创建 SessionFactory 必需的 DataSource ,执行持久化必需的 Session 及持久层访问必需的事务控制等,这些原本必须通过代码控制的逻辑,都将由Spring 接管 ataSource, SessionFactory, TransactionManager等,都将作为 Spring 容器中的 bean。将这些bean 放在配置文件中管理。$ {! a0 T6 T+ T
1、通用的资源管理: Spring 的 ApplicationContext 能管理 SessionFactory,使得配置值很容易被管理和修改,无须使用Hibernate 的配置文件。详细配置如下:) g( \ s" {2 D
a' N; i. M* o& v) b, M
class=“org.apache.commons.dbcp.BasicDataSource”>' ? v( g3 y4 G
+ m4 J) t Y" r0 d. L
oracle.jdbc.driver.OracleDriver
0 p+ K% _* E3 x# j0 ]
; }8 h0 k% A/ j6 u o ( e1 ^! l: \* _! w1 A: K8 ~( e
jdbc racle:thin localhost:1521 rcl: U# C" {6 x3 @3 @
! n8 W& Z, Q; e
$ P( e% ]1 @* Q: z, j javakc2
) P5 e K( ^- L$ ~ - _1 P& A8 z# m: g$ p1 z
* D4 N) K7 H0 h7 o
javakc2& R/ M* i) d& A( X. k: }8 I
8 L" o0 m9 H, d8 ]5 U+ E
7 x1 E O* T9 L; v: f+ g- k9 |
4 S- `8 E9 U7 g% ^! t class=“org.springframework.orm.hibernate3.LocalSessionFactoryBean”>, V: C5 s2 ~7 r2 w% w9 ?
$ j4 k9 f& g% P3 z$ i. h
- Q' D, m# _+ Q8 e8 k* X/ \ 6 |' |- r4 D8 x W: a, B' P2 l! Z: B
com/javakc/spring/h3/UserModel.hbm.xml
# Z# ?; f. A3 X' n' B ( i: z# Z8 e7 r$ J: z/ ~
9 Y+ S/ Y4 e, I e' n" ]
( y. Y/ N" ?4 J- _9 q+ P" Z
* s% U8 W+ O" X9 ]8 ~7 S; k hibernate.dialect=org.hibernate.dialect.OracleDialect- H1 p- h9 W |3 D
# C$ w1 H' @# V x5 P. G , P. ? s t2 Y$ D, G
! `# @8 P7 W- P! F $ [. O" s7 t+ y. y: i1 p" J! e
% R3 O% \2 V: Q+ o : i; }5 q3 [ Q/ e
如果需要使用容器管理的数据源,则无须提供数据驱动等信息,只需要提供数据源的JNDI 即可。对上文的SessionFactory只需将dataSource的配置替换成 JNDI 数据源,并将原有的 myDataSource Bean 替换成如下所示: class=“org.springframework.jndi.JndiObjectFactoryBean”>
" x0 s5 `5 F1 F1 ~/ v2 F2 x
" o/ k/ L2 L5 V9 J7 b. W! M java:comp/env/jdbc/myds
* X; N. C3 x7 C 7 F# c" f7 {' W' X. X4 ]2 s" l
2、有效的 Session 管理: Dao类继承HibernateDaoSurport后,Spring 提供了 HibernateTemplate,用于持久层访问,该模板类无须显示打开 Session及关闭 Session。它只要获得 SessionFactory 的引用,将可以智能打开 Session,并在持久化访问结束后关闭 Session ,程序开发只需完成持久层逻辑,通用的操作则由HibernateTemplate 完成。 3、统一的事务管理。无论是编程式事务,还是声明式事务, Spring 都提供一致的编程模型,无须烦琐的开始事务、显式提交及回滚。 建议使用声明式事务管理,Spring 的声明式事务以 Spring 的 AOP 为基础。可将事务管理逻辑与代码分离。代码中无须实现任何事务逻辑,程序开发者可以更专注于业务逻辑的实现。声明式事务不与任何事务策略藕合,采用声明式事务可以方便地在全局事务和局部事务之间切换。 Spring声明性事务有两种配置方法,一种是xml配置: 7 e) V- i5 {" |; w& y+ V8 I; |
# y- c2 S3 W5 U& e
6 i, V9 {) V4 S7 m. c
1 \$ E. Q2 \% Q+ g$ O5 E+ \
0 g3 C0 E/ u! j$ f1 O z 4 ?/ _, }0 N+ Z, M
. S5 B G4 F1 l9 e$ z
9 w7 V+ y, T4 {. k# l ' [/ O! h$ k" m
: W# v0 W' o, y# b) O+ n/ w
) [, n) Y* Y+ _, P6 r ! Z% h3 ] G' ?; T
( E* O4 W! a: O
; D# P7 U$ N0 U% m0 S8 W 另一种是通过注解,在需要添加事务的类上注明 @Transactional
$ ]% ~7 N' r' s3 \Spring2.0之前事务的写法" q7 I/ m2 F& w8 P: h. m4 U" j
' y* h" _% u, H( O+ b( y
1 H6 Q" `( O8 P) z" c class=”org.springframework.transaction.interceptor.TransactionProxyFactoryBean”; k+ p4 n- @2 N9 J! N; x
; {- w& @( X$ ?6 t# q7 w( M5 M% U! H) i
abstract=”true”>1 E6 i* o( L0 A% J- M
: S# O. l& V- ~8 y
, E3 U4 J1 V$ b$ S% x: R
5 p0 m& [3 l$ o$ Y5 A" s
/ S! i- P' I, e$ I' X/ ]3 d
PROPAGATION_REQUIRED,readOnly I; T; p* H1 {- b6 n. J
5 i6 ]8 c" U: E/ G PROPAGATION_REQUIRED1 _0 p; U; S5 K: x) i% f
6 n# R! x8 j+ ~' Z7 Q/ T
- V6 k4 L4 q1 h# E. W& C3 f$ i( B" d
( _5 K7 e0 I* K" u7 x6 [' K& J, h6 G, g0 Q$ W; o
| : j& k1 w- e# q# U6 d
. J8 V$ F" z i- q- {; Z4 ?- 谈谈Spring对事务的支持
' R, o$ Z& u" Z8 v+ v/ R* H! L1 C) c F3 s; w* `5 }5 m- o2 x% i, I
: Z; j) y. Q9 b! f, Y" p1、声明式事务管理:
1.流程:由客户端访问—-aop监控—-调用advice来追加事务 2.做法: 2.1 在配置文件的头中引入xmlns:tx 和schema的文件 2.2 2.3 注入数据源 ! `2 Z0 Z: k; L- s7 N) h3 t
- g! H0 L$ ^3 Q" }7 {1 y! R3 z0 x) s" }
9 {0 }/ N. Y7 I$ ]9 c$ ] e/ v( i( L! |- `* V
. A# u4 W6 \, ~6 V1 {, w2.4 由spring实现的事务管理,但需要注入数据源
" A0 U0 f3 j D- ^$ l% c6 S3 M; |; z# \5 y8 t5 w/ y
+ X, Q& w& d6 W# E! u' D h2.5 事务监控所有的方法(事务加强)
4 _ C5 o1 `% p9 u
. ]' n1 c( }; _7 X
- @5 x$ S; e6 q4 R& i( G+ g& j# u/ ?2 I" j, v& Y, g
) A0 m- B/ [7 w1 f5 `2.6 定义切入点
* k; X9 _# {! K' Q7 d' h& e$ C- Q+ q' f! e( y! d) [, e8 I
2 {9 w. ^- ~7 ^- j! u+ m; P$ s2 v
8 u- [ ]% ]+ b" O1 p3 t# l7 g X% s/ n& I" v2 h% T
2、使用注解实现事务管理: 1.注解@Transcational (可以在类上,也可以在方法上) 2.在配置文件中同样需要注入dataSource和spring的事务管理 3.使用注解的方法来追加事务 注解驱动
& t0 e$ w* p( { P @- K. Z& J5 h. \$ Q+ g! _% h# ]5 j6 \
如何在Spring中使用Hibernate的事务:! }# d( h8 K) U$ Q# {7 {9 ?( s3 Z
) w# L) h+ n# Q7 F3 W) H6 W7 u
9 Y$ S! z) Q' W) E , w/ z7 h( l* ]/ }( Y
如何在Spring中使用JTA的事务:
& s4 ?; V- b. h' f4 j6 j5 A 8 ^5 U& L7 ]$ B3 ]
|