Spring
) `" K6 e0 C6 C7 ?( _& |- 是什么?
2 J. _# @3 X4 V
; o% l! Y9 Q7 a0 E' v/ k! V
Spring是基于JEE的轻量级的应用框架 5 C- |+ ]) d' v* Z
- 有什么?# r- Y$ L Q8 k% G
* \ W' E' }6 I9 D Z4 @+ c
( @- O* ?( K; p, k) d9 G* W
每个包的功能: Spring MVC:spring 本身提供的web 框架 WEB:集成其他的web 应用的框架,或者说是对其他web应用框架的支持。如struts,webwork JEE :集成一系列的jee的技术(对JEE技术的支持) DAO:封装了JDBC;(对JDBC的支持) ORM:提供了对ORM工具的集成(支持) AOP :面向切面编成 CORE:spring的核心包,提供bean的工厂和IOC容器
8 \8 S6 c/ }8 P3 |" p* C' z- 能干什么?
! J. n }$ x& O+ H* n- } r/ D+ |0 e
把一系列的jee的技术有效的组合在一起形成以良好的系统
+ k2 U) p6 V- @& u0 i- 怎么用?
5 g5 T% m" y3 H* _" G2 G8 }& d# U; |) w z' X; I. a
- 搭建web工程,引入spring的jar包! o X, e% V+ x
- 在web.xml中添加如下配置6 E7 q4 Y( s) }# x8 \
( I0 P; B# a. \! ~; ~5 F, c) Q
. P K' N+ g+ {8 B7 s
' w6 l8 B. g# ]
contextConfigLocation7 D2 U; ^/ `/ C
classpath*:applicationContext*.xml
C b M) E: B5 o: k( ?) i/ M 8 K+ {* v& ~+ i v) X
2 m: r$ k$ m* t3 q; t3 C% X, ~# Y struts2
5 N1 W+ Q0 i" v, k, Q) u! F" L( {
8 U( N9 e+ n4 i+ _- B* m9 l org.apache.struts2.dispatcher.FilterDispatcher
u1 o6 {9 ^% [1 i ) R3 i* P: \# G! Y2 t9 x
7 _7 V0 M. q: s3 C, t3 j 9 B0 t* g- y( U8 O5 I( z% \6 P7 {9 Y
struts2; J7 k9 [" b4 g! H ~7 [
/*
) w/ P; T5 t, V& `' J+ y ) i: c' e; p, K: h
$ \& G# P2 _8 v
; I- e) q0 x: e
org.springframework.web.context.ContextLoaderListener% N( u$ k0 L; e. `% E e/ r
; l; ~6 Y6 t: o) } - 部署
8 l2 V4 h. Z" L/ ~
+ r9 p1 b6 i" x3 P- M8 _7 ? ) ~9 Y+ B+ Z, X4 B" d: d
" ]9 ~9 v* W- o$ D" @2 `( ], r2 A f
" l. L1 ]+ K6 F' ?- 容器和bean
0 v' X3 k3 X. c* T V
Bean :是指受spring的ioc管理的对象称为bean 容器 :(与jee的容器类比) Jee :提供组件的运行环境和管理组件的生命周期(不能单独存在) Spring :提供bean的运行环境和管理bean的生命周期(可以单独存在) # u2 Z! M5 E6 h4 L3 }1 U
. _! a: Q9 q. ^* n; R
- DI依赖注入
- o- S) K4 x9 z. C0 f& D P* H
1. 应用程序依赖spring注入所需要的对象 IOC和DI是对同一种事情的不同描述 2.setter注入: 在配置文件中将接口的实现配置为bean在应用程序中注入bean 例如: 在配置文件中
* x. s, Q J5 l* x- L" ]( u7 w% |1 \/ k8 [7 e
! \* x m( @/ y; j$ {, k在应用程序中 Public DBDAO dao ; Public void setDao(DBDAO dao){ This.dao = dao; } 3.构造器注入 - N, ~# z- l) j$ R
4.ref 表示参照其它的bean 在参照的过程中一定要注意死循环 5.自动装配———–〉no 自动装配根据名字来匹配相应的bean 尽量不要去自动装配 6.lookup注入 7.singleton 1.单例模式是整个的jvm中只有一个实例 2.spring的singleton是指在spring的容器中只有一个实例 一个生命周期中只有一个实例 8.DI的优点: 1.程序被动等待,强化面向接口编成 2.切断了对象或组件之间的联系,使程序的结构更加松散,运行和维护更加简单
( ]$ s4 r4 D6 n. M- Aop面向切面编程
. O0 l6 B7 U G3 A# c! t+ ~
8 K3 w3 w7 ]6 q
1.AOP面向切面编程 一些较好的模式或者是示例—-范式
' s, j0 l! ]1 \( ~" e1 G& p 切面:一个切面代表我们所关注的一系列的共同的功能点(模块之间的共同的功能点) 2.AOP的思想: 主动—->被动(追加功能), ?' f% S, ?3 F$ y$ H
3.AOP 的概念9 W; g2 `# ]2 {6 e5 P7 _
1.切面 :我们所关注的功能点 2.连接点 :事件的触发点(方法的执行) 3.通知 :连接点触发时执行的动作(方法) 4.切入点 :一系列的连接点的集合 (连接点的模块化) 5.引入 :扩展的功能 6.目标对象 :包含连接点的对象 7.aop代理 :实现机制 8.织入 :把advice和目标对象连接起来 4.AOP的事件机制
+ q' Z/ v: C1 Q9 j 1.通过切面找出一系列共同的功能点 2.找到目标对象(在标准的spring 中 接口的实现类为target) 3.找到切入点 4.确定连接点 5.通知spring AOP,查询xml文件,通过代理找到advice。 6.由aop代理来实现动态织入
0 w: M1 p) U, f$ F. E, P
, ]8 y7 }+ @! H8 c- v
9 Q- I( R/ n9 ^+ T; J* M V, x$ E" V' L" F% |9 e" Z% d8 A0 W: I
1 q9 o$ E1 O3 l; J5 m2 ~4 F$ W/ b1 Y
+ |( G. t1 L9 j3 p. D( p1 d9 k) ` Y; @6 Y" ~: k( Z
5. AspectJ
* D- K" `' W) s0 \ 5.1.在xml中配置比较烦琐0 K& q4 [# ~6 @0 l n
所有的入口必须从一个代理(ProxyFactoryBean)开始
( f* b; I' I0 l) ^ 1 L( F3 E V9 E* F! b: Z" C b$ i7 R
9 m+ j- I6 b. d& k2 D
' ]& s1 U* r: d; W
8 Y: k; K. l3 R! D
: j4 j, x3 {7 w$ f9 z: t& w
8 U% k) b: v8 X2 d# P0 n$ V/ a6 n
% R. W, K; l9 m" a& _
) A# M! A( {7 X& l4 fexpression=“execution(* com.javakc.aop.MyTarget.t*())”/>
7 K* b0 J. h; F& b# m' R0 F4 q' N
2 l8 F% N5 u" j# {! }' i) k 2 y8 h- D2 m5 X' }
0 L" M! b% A. F& ?
$ H" `4 Y; P% i$ v$ P- _' m, l3 m. N
5.3.使用注解的方法相对简单
. t( w7 B; E* h4 f, K5 C @AspectJ的基本语法
' ?& l9 \ U# `' j: ~ 1.@Aspect声明一个切面,将一系列的共同的功能定义成一个切面+ X' u$ T( S' g/ F3 L
直接在类上定义@Aspect; a- G+ b* X* M9 \) ]
2.@Pointcut声明切入点& g/ _7 a, O; c, `, }) M
2.1、用一个专门的类来定义pointcut,类中的方法名就是该pointcut的名字1 f+ E& V' N, O+ ~# e- K
2.2、可以使用匿名的pointcut: f4 G# v& Y& M
2.3、执行切点的几种方法" \" ]4 Z8 N; h S& z4 ?3 K
2.3.1 execute(public * 包结构.*.*.(..)) 可以指定到具体的方法
( Y4 f( Z! r7 Q0 ^1 R4 r 2.3.2 within 指定到包,不能指定到类' Q1 C% I/ L! `7 i+ u4 b
within(”com.javakc.spring..*”)9 c8 A! N- J1 G0 I
2.3.3 this 指定到实现接口的所有的实现类
- R- t" [ L/ {! Q$ ?8 E* ]: w 2.3.4 target 指定具体的实现类. J( r7 n) S7 \# D; A; O
5.4.advice的五种类型的示例, y8 k' ^* y! U
客户端必须从接口走才能得到监控,实现想要追加的功能9 U$ j! x9 }4 P: V
5.4.1.@AfterReturning(pointcut=”” returning=”retVal”)1 D: ^' a+ S, a- }+ n* h
追加的方法的参数名字一定要与retrning的名字相同/ l5 d) I7 z1 r# G
在注解@AfterReturning中必须加上pointcut和returning两个参数* Z U) b! ?, O1 J; L
pointcut指所要监控的目标对象的方法
9 z/ |, `3 Z6 X' b+ g 得到目标对象的方法的返回值,来作为参数,进行下一步的处理,参数没有顺序,按参数的名字进行匹配7 X& Z, i, j" Y" m
完成追加的功能! ~( a% W( Z @/ p9 q
1 定义一个pointcut,通过方法名来作为pointcut的名称来引用
( V& F' u" ]& g7 w (1).@AfterReturning(“com.javakc.spring.schemaaop.TestPointcut.t4()”)
# U. i6 U& h0 F: P (2).
$ I+ h1 H/ Q2 d/ j) P 2.直接引用匿名的pointcut
8 E. P% t: `1 @6 u; q (1).@AfterReturning(“execution(
# x; N4 C0 Z; |6 i4 u * com.javakc.spring.schemaaop.Api.test4())”)# ^" {1 D7 g( T( Q/ F' Y1 x
(2).@AfterReturning(pointcut=5 P& r& `' Q4 c) |
“com.javakc.spring.schemaaop.TestPointcut.t4() &&
7 \1 M, [0 ^2 {8 m args(str)”, returning=”retVal”)8 r' x6 Y0 L5 _# c) F' u/ c
@AfterReturning (pointcut=”com.javakc.spring.schemaaop.TestPointcut.t4() && args(str)”,returning=”retVal”)
b% L0 H- @" \1 Y public void testAfterReturning(String str,Object retVal){
& i1 ^2 P" H5 R" V1 Q System.out.println(“afterReturning1=>”+retVal+”=>”+str);5 a( H7 K' q0 E' ~0 l
}" u# k. O3 g/ @
5.4.2.@Aronud: Q: R9 o( f. _6 w, M5 m
注解@Around环绕追加功能;$ c& }) Z6 v+ Y+ a0 C% r
在执行目标对象的方法的前、后追加功能;5 X, I( T- X; R9 d
必须有参数;第一个参数的类型必须为ProceedingJoinPoint;
) Y; `7 ?& @* A. z4 T 通过ProceedingJoinPoint的实例的proceed来调用所监控的
8 Z% z6 m8 B3 K4 p; a3 o! p 目标对象的方法
& ~6 k, H; e0 m6 a! k 1 定义一个pointcut,通过方法名来作为pointcut的名称来引用6 g4 ^* g" a7 k! U: w
(1).@Around(“com.javakc.spring.schemaaop.TestPointcut.t1()”)
j/ y( s. [+ f (2).@Around(“com.javakc.spring.schemaaop.TestPointcut.t2()" @' l9 Y. R. j) x$ ^+ j: n& y0 _* J
&& args(str)”)9 k! \% R/ o2 Q" ^1 s5 s3 S
2.直接引用匿名的pointcut* v/ p8 p: E" F$ ]
(1).@Around(“execution(2 g, _% I: Q- z
* com.javakc.spring.schemaaop.Api.test1())”)
1 K+ m7 ]6 i% b) Q2 I& ~7 d# @ (2).@Around(“execution() m% @. T$ P* z
* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”). X6 C4 y W. f8 ?: j
// @Around(“com.javakc.spring.schemaaop.TestPointcut.t2() && args(str)”)
# h/ ?. V: @0 a3 m0 ]; z( o @Around(“execution(* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)9 F) _" R' f/ v' U" ^
public void testAround(ProceedingJoinPoint prj,String str) throws Throwable{
, l5 d8 h. x- `/ c5 m! g System.out.println(“around1==========before1pointcut==>”+str), _, p- x2 p, n( {3 P" k
Object obj = prj.proceed();
3 H3 J: j/ V+ k/ H, Q, l% l D System.out.println(“around1==========after1pointcut==>”+str);8 Y) x0 }1 h5 U% D* A+ |5 S
}
& ~; q. D; f7 S5 o o/ B7 u 5.4.3.@Before% r1 J6 F0 G7 t6 b7 n4 l8 E
注解@Before在执行目标对象的方法前追加相应的功能
* d ]: m& y* T' k1 [6 J* t 1 定义一个pointcut,通过方法名来作为pointcut的名称来引用# _! m' G/ X! a/ E" c( k& k. r
(1).@Before(“com.javakc.spring.schemaaop.TestPointcut.t1()”)- h; D: D( l3 P
(2).@Before(“com.javakc.spring.schemaaop.TestPointcut.t2() && args(str)”)
1 @4 h3 g9 P: s" I# H) a: u5 s 注意args后的名称与参数名相同1 f: ]1 K6 f3 o& T- Y- h$ u" _
2.直接引用匿名的pointcut* _' r: H2 v$ h+ o
(1).@Before(“execution(* com.javakc.spring.schemaaop.Api.test1())”)8 s$ O+ Z6 E a; K: F
(2).@Before(“execution(* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)
0 W8 D. e0 e! @5 b7 B" {# O, v 注意args后的名称与参数名相同
! y) F5 q, L1 {% i5 \; ^; x // @Before(“com.javakc.spring.schemaaop.TestPointcut.t2() && args(str)”)7 O2 Z) r- r' ?3 y& w4 Z* S( l# V( s3 J
@Before(“execution(* com.javakc.spring.schemaaop.Api.test2(..)) && args(str)”)
/ \5 ~1 y' p# T; i public void testBeforeParam(String str){* |; R6 \8 p. }0 p
System.out.println(“before1=param=>”+str);8 h& i8 \, c! d% z- V
}4 J* C, x6 p2 A9 z
2 t# _6 M0 ^, X7 g' Z
5.4.4.@After/ o4 c) |# v3 E, l9 I3 L1 X
注解@After在执行目标对象的方法后追加相应的功能
. b+ }$ u. w8 Q8 Z f B) Q 1 定义一个pointcut,通过方法名来作为pointcut的名称来引用
1 Z. a& g$ J3 q, s" e. y) v* { (1).@After(“com.javakc.spring.schemaaop.TestPointcut.t1()”)
! M+ B5 S' G g7 N: E$ s" q 2.直接引用匿名的pointcut
- }3 k: r( j" X2 u (1).@After(“execution(* com.javakc.spring.schemaaop.Api.test1())”)
/ F/ e) X6 \2 c; B- W @After(“com.javakc.spring.schemaaop.TestPointcut.t1()”)
0 m: h6 s( U: F public void testAfter(){) b! |$ Z/ E6 Y( ]
System.out.println(“after1== >pointcut”);
6 ?/ [/ q Y0 X$ u }
. l }( Y% _. u 5.4.5.@AfterThorwing( B# g4 x/ m0 }* M& ~, ^
% G8 X- ]8 |# ~9 _' C/ \0 q6 E
5 {* |1 |8 e1 Q# s
- 描述一下spring中BeanFactory和ApplicationContext的差别) f% e2 b! ~& s& m' x9 ?9 ^# J" A
2 a8 L+ b& d4 R2 `$ u
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”);
& ?+ X; |/ O: i; @6 H7 G# [- 谈谈spring对DAO的支持% m* z: m1 b+ `2 h
0 V2 B9 E7 `- O! m& t2 n
Spring提供的DAO(数据访问对象)支持主要的目的是便于以标准的方式使用不同的数据访问技术。
* W8 l! z, J* H& w 简化 DAO 组件的开发。% F0 z) r3 b7 _0 W4 T% ]
Spring提供了一套抽象DAO类供你扩展。这些抽象类提供了一些方法,用来简化代码开发。
1 Q; d* X* `& \9 A6 h IoC 容器的使用,提供了 DAO 组件与业务逻辑组件之间的解耦。所有的 DAO 组件,都由容器负责注入到业务逻辑组件中,其业务组件无须关心 DAO 组件的实现。
) R. P' K' S/ ^: P- w y1 n 面向接口编程及 DAO 模式的使用,提高了系统组件之间的解耦,降低了系统重构的成本。
( b0 [5 Z4 {$ d4 \* U" G Q 方便的事务管理: Spring的声明式事务管理力度是方法级。
& X; W: r. h+ Y% H6 G- D 异常包装:Spring能够包装Hibernate异常,把它们从CheckedException变为RuntimeException; 开发者可选择在恰当的层处理数据中不可恢复的异常,从而避免烦琐的 catch/throw 及异常声明。
" u5 }1 E1 l6 D/ [1 s( j9 t) J- e
, Q1 ^! ~- I. x% E6 b' x* l: l9 e( g9 i( u
- 谈谈spring对hibernate的支持6 A% _6 h# r0 N* R4 a3 u- T) V
7 g3 C1 H8 I1 V7 L) T
在所有的 ORM 框架中, Sping 对 Hibernate 的支持最好。如 SessionFactory 的注入、HibernateTemplate 的简化操作及 DAO 支持等。另外, Spring 还提供了统一的异常体系及声明式事务管理等。
8 ]4 O' ~; f5 Z3 p5 ^5 b 一旦 Hibernate 处于 Spring 的管理下, Hibernate 所需要的基础资源,都由 Spring 提供注入。Hibernate 创建 SessionFactory 必需的 DataSource ,执行持久化必需的 Session 及持久层访问必需的事务控制等,这些原本必须通过代码控制的逻辑,都将由Spring 接管 ataSource, SessionFactory, TransactionManager等,都将作为 Spring 容器中的 bean。将这些bean 放在配置文件中管理。
" W% q1 x8 [# G* J. d 1、通用的资源管理: Spring 的 ApplicationContext 能管理 SessionFactory,使得配置值很容易被管理和修改,无须使用Hibernate 的配置文件。详细配置如下:
$ O' X' J* R! @6 I7 k$ e% ]
6 K: G# T6 J7 e. r1 G4 w) `1 P% c# ~ class=“org.apache.commons.dbcp.BasicDataSource”>+ b& P/ u5 }6 Y/ J' q; G
2 P% o7 |' B8 D! V8 ?" B
oracle.jdbc.driver.OracleDriver. u) f9 I( ]5 w _% V) V1 S
. J* H& G, }+ h6 Z; s. s) K7 b
+ X7 F3 f M! l" i) F jdbc racle:thin localhost:1521 rcl& O0 x4 [: @* m% L! S1 W7 O
5 C# q( j" v, G4 w; a
- q4 c' h. u; p5 ?% s- z _8 n' G javakc2
s7 M+ @# a$ H" W* d 7 ]" R8 @7 L7 R' F; b* g
& h1 {1 n9 {8 T4 t javakc25 f1 c+ w/ r/ c- `% u7 z
2 Y- y2 W; L c2 T! Q
; A, b9 q4 J! l t% X
' I0 Z3 e9 v& f+ w. o! |3 B% c class=“org.springframework.orm.hibernate3.LocalSessionFactoryBean”>3 n4 \1 p) X/ V" r( w8 {1 V- V
5 V) T* \/ @& M# t5 B' B4 } 4 b5 F G2 Z& O
2 s- z$ ~. Y" @$ c
com/javakc/spring/h3/UserModel.hbm.xml9 u, a% f/ g5 H4 W
9 S4 J2 k7 \) F) J5 l 4 a: C6 r+ h( j0 y
0 Q) a# E9 i( m: `+ x
* v& X/ Z. u; w3 H$ S* W hibernate.dialect=org.hibernate.dialect.OracleDialect
6 s/ W* R3 I5 ~+ p " C7 h* p) ^' I' t# t) J
% Q7 q; f8 w. n2 @
& y1 j+ T( h& ?0 {
5 v2 N( }" Y% {7 f3 e
& @. h, [5 s( ?' ^% m 0 |2 u/ o; V4 h' T
如果需要使用容器管理的数据源,则无须提供数据驱动等信息,只需要提供数据源的JNDI 即可。对上文的SessionFactory只需将dataSource的配置替换成 JNDI 数据源,并将原有的 myDataSource Bean 替换成如下所示: class=“org.springframework.jndi.JndiObjectFactoryBean”>' U2 C0 S' T, U) j% O; T! H
1 w7 m! d( j& i- _9 `
java:comp/env/jdbc/myds6 o0 m: E1 H' G
- ~1 V3 o+ W' l6 Y2 C& H 2、有效的 Session 管理: Dao类继承HibernateDaoSurport后,Spring 提供了 HibernateTemplate,用于持久层访问,该模板类无须显示打开 Session及关闭 Session。它只要获得 SessionFactory 的引用,将可以智能打开 Session,并在持久化访问结束后关闭 Session ,程序开发只需完成持久层逻辑,通用的操作则由HibernateTemplate 完成。 3、统一的事务管理。无论是编程式事务,还是声明式事务, Spring 都提供一致的编程模型,无须烦琐的开始事务、显式提交及回滚。 建议使用声明式事务管理,Spring 的声明式事务以 Spring 的 AOP 为基础。可将事务管理逻辑与代码分离。代码中无须实现任何事务逻辑,程序开发者可以更专注于业务逻辑的实现。声明式事务不与任何事务策略藕合,采用声明式事务可以方便地在全局事务和局部事务之间切换。 Spring声明性事务有两种配置方法,一种是xml配置:
/ A/ t0 G) |% T ; Q! ]0 [7 G2 U& Z- @
- { W5 f+ q2 x) e% \ ( d# B7 V$ D7 m( t" m# s
3 _! ]7 d! U8 `6 [8 F( d
* }: V! q) B# y
: M/ n+ p0 ]3 ~, I6 o
! W7 A% F5 R# P' ~4 F# }1 d" o % O. L/ \ x3 U7 i: r
% |0 I1 `4 T6 D+ g4 e9 h
0 w/ F! P: R1 n) M
_* b( S8 @& U/ V5 \
4 p4 _2 @, k) [% S
9 w) \; K5 u3 D$ G$ Q: p- a5 f
另一种是通过注解,在需要添加事务的类上注明 @Transactional
' ?6 y; O5 Z& I+ M! O6 {( LSpring2.0之前事务的写法0 ?& A. q! {4 K
7 J" a3 b5 M; }1 Z' O! u% W
' J( V, f& c: J/ I% ]: h class=”org.springframework.transaction.interceptor.TransactionProxyFactoryBean”2 x- }& U$ J6 X' j# V
\! R; Z L$ e1 M abstract=”true”>
% N+ l% k5 W9 C4 m* i5 d Q9 p3 r$ x; |& x* V( K- u
* w! o% M# N1 Z t4 ^) v: K! I6 {/ H+ G ^# S3 m
5 X Q; m) I2 x. ^+ u6 m1 A
PROPAGATION_REQUIRED,readOnly& A7 H9 M# y+ g# r8 t. @
0 [1 N% ]* v' ]- {% w: C6 f
PROPAGATION_REQUIRED
j2 @2 }# R3 c0 |# O0 [9 M5 `7 ]8 P2 C4 s
}7 C D9 I/ ?4 K; c: N: `
4 w1 m, G- R8 b' U% b# W, V1 g2 H& O
| t& Z6 _* w2 b: R
5 A% o* e5 b# z2 t" [, H6 z
- 谈谈Spring对事务的支持: m- S. y9 o+ O0 j3 c& T2 }
1 w& K+ ?, F; P8 i
' R" `$ h: A* q' H+ x7 S
1、声明式事务管理: 1.流程:由客户端访问—-aop监控—-调用advice来追加事务 2.做法: 2.1 在配置文件的头中引入xmlns:tx 和schema的文件 2.2 2.3 注入数据源 1 X U# F. g: `9 X, X) f E, N
7 X# B5 _% H, A- z( Q' m7 s
; a0 I- n2 Z% [2 v/ e' o/ t+ V E5 f: }! v& O! |
6 |$ v8 Z# {) Y- \- M9 b, J
7 {) F; Z+ N3 ?0 O7 O( ^" k2.4 由spring实现的事务管理,但需要注入数据源
- ^0 ]# R$ Q- n, ]& J! E( X
6 x8 }, t8 |3 M5 X5 w( i& g9 F$ E& P* E0 W( a5 T
2.5 事务监控所有的方法(事务加强) 6 V5 L6 N/ I6 b U+ r% I% W: z1 b
) r7 y6 R! `/ l8 @7 w( ~5 h( N
: n, G+ J' X. L5 H7 K" U& r, S* I
, _4 u! ?) T: M' y' S% |
7 j# }; m, E; H L- T2.6 定义切入点 " q. y8 L: b# a# f/ ?
' l4 o0 }/ ?- v! e3 p$ z5 n
5 Z) R; t+ N& L' w: \9 r+ Q! D; Z5 [9 x2 E# e/ G* @
0 r3 f# a# g, G6 H
2、使用注解实现事务管理: 1.注解@Transcational (可以在类上,也可以在方法上) 2.在配置文件中同样需要注入dataSource和spring的事务管理 3.使用注解的方法来追加事务 注解驱动 2 S6 t4 j* Y. I {% D& T5 I
* N* [ o+ {8 @8 o+ P如何在Spring中使用Hibernate的事务:
$ `' X7 g F* A" i r7 h5 I# I7 k
0 F! D7 L! T; q) S% s
) r- _7 ]7 l2 p9 D如何在Spring中使用JTA的事务:
' I& L P7 K4 s / C8 A0 e, V8 o- J8 X3 k
|