该用户从未签到
|
1、创建Web Project
; R* ?( V9 j9 `0 k5 g2 H6 |0 e3 }2、web工程与struts2整合" }) |- [' ?# V
(1)添加struts2类库. Z; Y1 q+ a& r7 k' K# p9 @- n
struts2-core-2.1.8.1.jar
+ q7 r2 F( ?+ F/ Y! E9 [# o" m0 y0 H xwork-core-2.1.6.jar' J& h3 p) ?+ u
commons-fileupload-1.2.1.jar# L4 G/ N, Q$ y: N
commons-io-1.3.2.jar! C# H, @0 S1 a1 ^3 b B
ognl-2.7.3.jar0 a' j7 z8 l( b/ @8 m
freemarker-2.3.15.jar3 ?7 C' V8 E. h* q! P# i. y+ x8 ]
(2) 在web.xml文件中添加struts2集成
+ W0 ^- G, I( {( e3 H" P8 l: C: r- C. ~ <filter>$ v! l6 A9 @7 ^) _2 P8 Y+ Q
<filter-name>struts</filter-name>
& f6 K: N5 ~6 t5 ~ a) P <filter-class>8 v6 Q9 |3 }- S8 _' _# u2 z# [
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter3 E6 N2 X- K. `
</filter-class>
9 i* Z6 }0 V7 j+ x( s, p4 w1 ` <init-param>
. l( _+ T1 M0 s+ N% }3 X# X: P% ^ <param-name>config</param-name>: m) B( g3 X5 x: g
<!--+ y' a# s. U8 G0 P! [
修改struts2默认配置文件,
& `- v/ M/ w, v5 @ 必须把struts-default.xml,2 W9 y! h0 B* E7 o& w
struts-plugin.xml一起添加
$ @: y/ G! J" l# ]* e# q; J 必须:按顺序添加
: x8 n5 a$ x7 E# Z* O4 f6 R -->
& @( j1 Y$ x/ U/ n) e ^ <param-value>
: N7 ?* Q& ~. E( o struts-default.xml,struts-plugin.xml,config/struts/struts.xml6 k6 u) J& A: c5 i1 X4 I
</param-value>
0 R5 R1 \2 _7 f6 P </init-param>* r# v7 X( ~6 g4 v
</filter>
$ B! `( W% z0 X( J" x/ c6 `1 m2 ~ <filter-mapping>
# w- ^0 | Z$ r <filter-name>struts</filter-name>: e0 A% v2 o8 r, S" y w
<url-pattern>/*</url-pattern>0 x' K9 i1 z& X& g8 h5 Q
</filter-mapping>
0 {9 Z; }1 l: F( L <!--struts2 *.action struts2 *.do-->& O1 d v! m. h6 X/ }& ?0 g5 V8 M
(3)创建struts2配置文件struts.xml配置
# n' i& i$ f1 {/ q8 m (4)完成页面跳转 b5 v# q* D, x7 S3 M# w5 e# ~
3、测试struts2工程
$ W0 J* b, F% y% M9 _4、struts2与spring集成6 @& T: P8 i5 A( \) ?" z
(1)添加spring类库与struts支持spring插件; Q1 L. X3 ?$ T* [0 L
struts2-spring-plugin-2.1.8.1.jar2 O: Q9 X* J n4 s h: X, T; Y
cglib-nodep-2.1_3.jar& ?1 u( D, M% M
commons-logging.jar* O% |2 m; f$ y+ c- a
log4j-1.2.15.jar
& }; ]7 Z8 D/ K! O" }" Q spring.jar
7 V& ~& m2 n. t( f& D7 | dom4j-1.6.1.jar) m$ I4 H5 X3 j$ E, e7 M
(2)在web.xml中完成spring集成* g- x1 g, t7 t K9 w! P8 |
<listener>. x0 r3 V8 Y. W" Q% a: y5 Y
<listener-class>
) a. ]$ [" ]8 H N8 H org.springframework.web.context.ContextLoaderListener% T4 ?2 h3 n% r' V3 B6 h" l
</listener-class>8 q) h0 b( U* j, g2 D) ]" ^
</listener>
" h' ~& [3 l- | <context-param>
9 Y" z. Q+ v1 v1 ]7 I <param-name>contextConfigLocation</param-name>5 a. K: l5 z4 W0 L; E$ P5 |; E
<param-value>! Y6 O: |) \# f# ?2 u9 t# {
classpath:config/spring/applicationContext.xml
. M) C2 W" S8 G* I ^" m# [ <!--classpath:config/spring/applicationContext*.xml-->$ t- W M/ i8 b7 W
</param-value>! y! `% X& y/ e. B n2 ]
</context-param>
/ W9 n+ k( c" p+ s5 @2 n( m! B$ D. U (3)创建spring配置文件applicationContext.xml
5 `+ n, t) A: E* w (4)在struts2配置文件中添加spring 集成常量, F) A; u% u8 }9 r( a1 c5 h
<!-- 设置集成spring框架 -->
, e; \* ~3 h" E( ^5 Z <constant name="struts.objectFactory" value="spring"/>+ p5 B- Z% _" O
(5)spring管理struts2中Action5 d/ p, M( b5 J- `
(1)在spring 配置文件中加入bean管理
7 a% ^0 D: {7 x <bean id="userAction" class="com.tarena.web.action.UserAction" >
. z* A9 S( n3 M" N2 X0 e$ c/ ~ </bean>
( K5 L' u2 D& g6 K (2)修改struts-user.xml配置
* H& U w; P+ Y0 f4 G" z5 v6 Y) n <action class="userAction" >
1 J9 S- p( u; R7 k6 Z* u </action>
! M9 ~! r; {! ]- I6 |' c! P0 Q6 d5 测试struts+spring集成5 _6 t2 t, S( X9 W+ ^. D" m* ?
6 spring+hibernate集成: ?7 W1 j" `) E
(1)添加hibernate类库
0 O" W2 [: n6 R0 q) d slf4j-nop-1.5.8.jar
7 a+ s/ w& f0 Q: K- D slf4j-api-1.5.8.jar
! ^8 m7 @) _$ K W, y- a. G4 P jta-1.1.jar
, t+ {( v# \! _- T5 N javassist-3.9.0.GA.jar
% N! F! q$ H) j! v4 K( \ hibernate3.jar" Z4 \1 S) G9 p! w( P
commons-collections-3.1.jar+ S7 F3 I9 q3 @) u
antlr-2.7.6.jar
+ F* @9 K; a" s" l0 { (2)添加MySQL驱动类库
0 z* M+ g' m0 v4 {' H4 D/ O5 \ mysql-connector-java-5.1.16-bin.jar
7 b4 B# p: |3 J. @0 x$ C (3)创建实体类
9 D8 b1 v- u2 J) f2 l" w [ (4)编写User.hbm.xml映射文件
9 }1 E, J% @4 j: d/ u4 a9 n/ Z' D (5)反向生成表结构! I7 B( }9 z) G3 x6 I9 q4 {5 w8 M
(6)spring管理hibernate
, {. J* O& K( h, x2 j) U9 I" }8 k 在spring applicationContext.xml配置文件中添加spring对hibernate管理2 d \: V/ P" D1 i3 v
(A) 添加DBCP连接池
: ]: |# C5 ~, d% k3 W0 a a、添加类库. o0 a3 \; F$ Y" G; V% r
commons-dbcp.jar0 B d4 W; n; x
commons-pool.jar0 c" L+ G- S6 w: @/ Q7 M/ i9 \
b、applicationContext.xml在配置连接池
# w% S! @: Q3 H <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">0 y. y& o& l4 D. Z
<property name="driverClassName" value="com.mysql.jdbc.Driver"/> O6 ]2 E2 O- i
<property name="url" value="jdbc:mysql://127.0.0.1:3306/mydb"/>
. M: _4 }7 k+ R& e$ I- v2 W <property name="username" value="root"/>
6 G3 Q! D8 w0 H9 ` <property name="password" value="1234"/>6 J% P/ ] m' I5 \
<property name="initialSize" value="2"/>8 Z1 d6 C; N. `
<property name="maxActive" value="8"/>
" D4 T: t; g e <property name="maxIdle" value="5"/>
3 D* Y/ o J6 E <property name="minIdle" value="3"/>
- f) l, E, J v! p7 e+ t+ n <property name="maxWait" value="3000"/>0 Y: a' [0 {- W& O4 X2 m+ ~
<property name="removeAbandonedTimeout" value="60000"/>
& M3 Z7 q. z& ?* D0 V( C+ N <property name="removeAbandoned" value="true"/>& g/ k* s9 T2 k5 e
</bean>8 g# }, x" t( ~& V
连接池参数如下:
0 e2 X8 J5 T2 `* \+ { initialSize
# o, i! ~* V4 g% f 连接池启动时创建的初始化连接数量
+ g; X5 ~* j, l. D (默认值initialSize :连接池启动时
; q0 _7 R3 ^! ~ 创建的初始化连接数量(默认值为0)
) ]* A0 \( x: a$ H% q maxActive
# M* ~4 |9 c8 a+ v$ R Z6 c 连接池中可同时连接的最大的连接数
9 \+ [/ w# e2 e6 o9 w' C4 q (默认值为8 ,调整为20,高峰单机器在20并发左右,, i) ~& T4 I! J F& J
自己根据应用场景定) 0 q! I5 j0 [! N, w8 z
maxIdle+ w( h D# W" p8 x8 Y! [
连接池中最大的空闲的连接数,
- E5 e* \$ u- l; X! Z$ ` 超过的空闲连接将被释放,
9 ]( |. b4 X/ h2 v* G- ? 如果设置为负数表示 不限制(默认为8个)$ ]5 Z! c; r+ `" F. |4 u0 _
minIdle; l0 B/ V3 d4 t. r- ]4 [+ v
连接池 中最小的空闲的连接数,低于这个数量会被9 }! f% f. B% h1 [& L) ?1 d% J
创建新的连接(默认为0,调整为5, 该参数越接近, l' ]# x$ w# `/ ?2 R3 w' K
maxIdle,性能越好,因为连接的创建和销毁,
3 } ?: a! f5 z7 b% i0 d 都是需要消耗资源的,但是不能太大,# x3 ^1 L' j6 ?9 A! `
因为在机器很空闲的时候,也会创建低于
4 g: S( i& O/ m minidle个数的连接) : |- L' s I8 ~
maxWait
* a0 U: G ?% O j 最大等待时间,当没有可用 连接时,. ?0 Y7 v8 z, [ \/ }
连接池等待连接释放的最大时间,: Y6 q% ?3 _8 D; C/ T! C
超过该时间限制会抛出异常,
A& n! M" D. h5 C/ F 如果设 置-1表示无限等待(
, x: J/ Z, w0 F9 y6 g9 m 默认为无限,调整为60000ms,
8 n: j; l" t0 D: S% L: Z 避免因线程池不够用,而导致 请求被无限制挂起)
% w0 F9 `) {: h' h: g- }0 a% _ removeAbandonedTimeout :
" j) k5 m0 u4 P$ S8 z 超过时间限制,回收没有用(废弃)的连接 ! r; I) }( n: ~" c
(默认为 300秒,调整为180) ' x% ]7 s5 R/ `% K
removeAbandoned :9 [+ Y; q4 M6 D0 |) P) ^) W
超过 removeAbandonedTimeout时间后,
2 v ~2 V! |% c' k 是否进行没用连接(废弃)的回收- d- q: `0 W5 p$ T$ U2 L; z
(默认为 false,调整为true). E9 o3 t, J0 ] @8 v4 F" `. ^
(B)spring管理hibernate实体映射文件:9 Q" `$ ^1 R& A: x
<bean id="sessionFactory"% O$ S" H4 Z3 L8 o) @
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">' `5 ?5 X5 U* s5 j- J" g) t4 x9 g
<property name="dataSource" ref="dataSource" />
/ C R a/ w" ?& ]6 P( t! J2 K$ c <property name="hibernateProperties">: L# c! q2 ?' f( l6 V! [
<props>
4 y* ?" `! `* T6 Q- c# k# J( g <prop key="hibernate.dialect">0 \9 p7 b& d3 i
org.hibernate.dialect.MySQLDialect' x2 z- l& {8 I3 Y* I+ `+ b5 d- O$ y" L
</prop>0 e- b5 r/ w8 e9 O1 E
<prop key="hibernate.show_sql">true</prop>
' C& v" P4 w/ N/ ]+ K <prop key="hibernate.format_sql">true</prop>( W- V+ t; O0 m- v/ Z- o
</props>
4 ^5 |4 X8 _3 O1 a </property>; G/ }/ O6 O$ J" a& |; ?
<property name="mappingLocations">
) ~7 t. M, h( p! e5 a <list>
, ~( L8 V' c, O% i) n <value>
. C+ [+ X' @8 G5 r1 f. `8 {9 R9 x classpath:config/hibernate/hbm/User.hbm.xml. T1 C( o5 t+ @7 E
</value>2 [- Y- G: e2 N' R1 O* i2 L& m
</list>
3 Y9 B5 s$ p @6 G q* O* f8 K </property>1 \8 T( [- Z5 V9 Z; W# T- E, k
</bean>: Z& A2 Z2 P8 F: C5 R+ R6 U2 v
(C)spring读写属性(properties)文件' k" T' i! C- S4 y2 v
a、创建属性文件 db.properties
# {7 l' z! c: y) O2 ?+ s: P# N) Z b、在applicationContext.xml配置8 }/ U+ Z4 ]8 P: X* u& ?! _
<bean id="propertyPlaceholderConfigurer"
( u$ z( v8 _8 T3 U6 \) F* c class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">. b+ S1 ]/ f4 P6 @' E- _$ m, c
<property name="locations"> T6 J: N7 v* S3 J
<list>, @* n9 `% o# x+ {$ o
<value>classpath:config/props/db.properties</value>
- G. Q& h) A/ Z# r8 X </list>
) p, f' h+ s/ d6 h) H S. d </property>
9 z2 @/ a8 r$ ?+ \/ Y r </bean>7 }, L. k9 `$ X! S5 P
c:引用: ${username}# ^5 f# s K1 s$ `" B0 ?) t9 q( i% t
0 O# r' ^9 w& B: \6 W# Y2 @ (8)spring分文件管理
, l/ x# y5 @+ a+ u5 r2 a. k; I <!-- 引入其他spring 配置文件 -->
# G/ `' a9 ~3 o( \8 c4 n applicationContext.xml引入下列文件8 `$ {! X# d" o8 E) L
<import resource="applicationContext-web.xml"/>4 T5 q. d1 ~' v# [, \' q4 r+ \
<import resource="applicationContext-biz.xml"/>
% n# m" |4 ]6 x$ w! w7 G e+ v <import resource="applicationContext-dao.xml"/>' V, f* d3 D7 h
7、开发数据访问层
+ L9 p: n- Y. H0 `2 a 使用spring提供hibernate 模板类 HibernateDaoSupport
) M- J7 ^& t8 j4 N& I5 c UserDaoImpl extends HibernateDaoSupport6 ` T/ R [4 {' R
在UserDaoImpl注入到spring 配置文件 applicationContext-dao.xml# Z3 ?4 p: t5 S# Y+ X
<bean id="userDaoImpl" class="com.tarena.dao.impl.UserDaoImpl">
2 R. a2 @/ H# g8 ~9 v' n <!--HibernateDaoSupport中的sessionFactory-->2 I( n: Y+ e. k* h$ y
<property name="sessionFactory" ref="sessionFactory" />: a. a; o- t0 Z" Q, `
</bean>
7 F9 @ e7 Q" p8、添加spring声明事务管理(AOP)7 n9 ?: f, M9 b# w7 S1 ^) g
声明式事务管理:' _/ J6 ~) V$ S! e/ S, M+ h
添加spring 类库( H4 ~. f" A9 k! C
aspectjrt.jar' p+ k, a( c, m' I, W
aspectjweaver.jar; N; Q5 U! A2 c/ u3 v1 }) e
了解事务的几种传播特性
2 s. w4 m ~! |' r) L0 ~+ D8 _( {0 Y3 s
(1)PROPAGATION_REQUIRED:
- p& G* S6 u- p 如果存在一个事务,则支持当前事务,如果没有事务则开启。
9 Q1 W1 u) J' t* ^4 G7 Q (2)PROPAGATION_SUPPORTS: 7 u# B0 @) l& H3 g- L G L! L
如果存在一个事务,支持当前事务。
. H7 Z) c5 |/ c1 ]; k [ 如果没有事务,则非事务的执行。% ~: C/ g5 q' h- f3 @, E4 U# k
(3)PROPAGATION_MANDATORY: 5 P, M. D. l( j/ `' ] @6 `* ^) q; e
如果已经存在一个事务,支持当前事务。5 _3 h# y4 I( t, G* y, w
如果没有一个活动的事务,则抛出异常。 }# z& b& H& ^! ?* S- e# C
(4)PROPAGATION_REQUIRES_NEW: : O4 W7 I$ b9 E) U& ~& r3 X/ c3 t! n! L
总是开启一个新的事务。如果一个事务已经存在,
- l9 V' |( K% Z& g0 k 则将这个存在的事务挂起。( Y3 v# G% u/ E5 \& @
(7)PROPAGATION_NESTED:(spring特有)- d' A6 W: c8 x1 l4 j" X/ n
如果一个活动的事务存在,则运行在一个嵌套的事务中.
: \3 k5 h% D6 s% m. j6 b 如果没有活动事务, 则按TransactionDefinition." |( i) J& [& f
PROPAGATION_REQUIRED 属性执行8 V, V" T# X3 c0 ], A+ ]
5 i. N2 o; N+ A" e (5)PROPAGATION_NOT_SUPPORTED:
1 h% v! U% g& w' Z2 ^ 总是非事务地执行,并挂起任何存在的事务。
1 W6 R% {, m* g (6)PROPAGATION_NEVER: : p4 y1 k% k6 Q3 {% f
总是非事务地执行,如果存在一个活动事务,则抛出异常。
0 c$ M" x) e! u% `: l: G" M5 V* P& `, Z
( R* n) B+ ~' U
<!-- 配置声明事务管理 spring2.x-->! h6 J; B+ B* s( o8 _0 e U
<!-- 定义事务管理 -->& \4 B1 K) C, A8 w$ H' }) |9 E
<bean id="transactionManager"5 @. s8 A0 Z# y; b7 v# a* L+ G
class="org.springframework.orm.hibernate3.HibernateTransactionManager">9 Z# b5 B: s8 ?
<property name="sessionFactory" ref="sessionFactory" />
# V- ^. ]7 k% [$ z8 m# ` </bean>& Y8 b% R9 ~+ f' q4 d( G, V- _ _2 \
<!-- 事务规则 -->
' e$ J6 u( v9 R2 i/ F8 I& m <tx:advice id="tmAdvice" transaction-manager="transactionManager">9 Y0 {. v% v7 K* {' ^9 }: W' ^
<tx:attributes>" W, o# D3 V: Q8 G' e
<!--*通配符 save* 方法名必须是以save开始-->
; b( }% Y' S9 } <tx:method name="save*" propagation="REQUIRED" />+ f& y$ A- y K' j( ^
<tx:method name="update*" propagation="REQUIRED" />
- E: }- ]1 \" S" J8 P* z' N, v <tx:method name="delete*" propagation="REQUIRED" />
: P8 D- t; i6 e/ @* T4 @ <tx:method name="find*" read-only="true" />
) b2 k! ?4 j8 b* w4 V O <!-- read-only 只读:-->4 O# V% w# t# e' E3 ^: D
</tx:attributes>$ c/ z. M0 _( o6 L4 l& U
</tx:advice>* n9 s/ o- E0 J) N! r! `/ v# o3 b
<aop:config>
% ]2 g* H/ g' o6 X: R5 B& g; l <!-- point cut -->
* \4 y, s- C9 v# l( s2 M" j <aop:pointcut id="pointCut"
7 [# G+ \, u3 K7 f3 T7 r' q6 k expression="execution(* com.tarena.biz.*.*(..))" />: H3 M. o* M9 T" f
<aop:advisor advice-ref="tmAdvice" pointcut-ref="pointCut"/> " p% H# A6 I6 Z" J
</aop:config>$ B0 y, u4 [' n5 W; E
$ t+ r0 Y4 n4 r/ g
9、测试
3 b" W, q0 ^# L8 U" |2 W! X# P 添加测试类库 spring2.5.6
% G* b# f8 d' v3 y( X3 Y* X/ W junit-4.4.jar A9 u" o1 d+ I- ?
spring-test.jar, k% S0 ], U& w( j. a+ v% U; o
//使用spring测试
1 M/ H6 Y0 u+ l8 f! i* T0 `% h7 y @RunWith(SpringJUnit4ClassRunner.class)
7 h$ e. }# d' e" N% y: c; Q //加载spring配置文件2 R' s$ p9 q, }) C+ P; h _
@ContextConfiguration(locations = {% I/ v; C+ D% E0 ~# B1 I+ E( o* p& i
"classpath:config/spring/applicationContext.xml",
! X. o! u# K' g% G9 W9 z3 n "classpath:config/spring/applicationContext-dao.xml",; Q" W" a0 I. O w
"classpath:config/spring/applicationContext-biz.xml",
: h; G5 }% F0 ^& a "classpath:config/spring/applicationContext-web.xml" })
( x+ K6 H' {3 o- ~2 } //自动注入
% w b4 P1 l0 R! a( R @Autowired
% a' o7 V6 M- b! Q private IUserDao iuserDao;8 Z# k* Y* Y, F4 v- V2 {
# L/ C8 {; T' C+ X; @4 f3 f) Z
@Test( `, j0 o6 E# l" M5 Y7 R+ ~
public void saveUserTest(){" j$ }8 y/ n4 F9 R7 q
//测试方法5 }5 |: Y4 Q$ D+ a
}
! r- j1 P. D6 ~10、完成业务层代码编写
$ W7 W+ ?: O; g" p$ C: k6 t11、完成表示层代码编写
; ^/ K/ |5 B' Z; i: f" k5 a+ C12、测试工程
; g4 ^. _: a6 h/ u f' N% B
* v2 A% }5 B$ D1 o8 L& Y2 @13、spring处理hibernate延时加载
3 K" l& S4 W3 ` 1、配置延时过滤器
1 \+ K5 h; i+ E) C OpenSessionInViewFilter.class% F, t: Z, g; \5 i) C- e2 e% J! ^" ?, y
2、在web.xml配置OpenSessionInViewFilter9 B% [/ P5 a3 M5 x5 D+ l$ { |
1 E( H6 M8 [: T0 U- D
<filter>8 E* {! j' C9 Q: Q+ z* O4 }( k
<filter-name>openSessionInViewFilter</filter-name>, L6 D* ~& a9 D( F2 H5 A
<filter-class>
! u& g7 O o: ^- I org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
# H& t6 v+ R5 `! L. e1 I0 H+ b </filter-class>
: {" S$ {) d& ?: O/ n9 o, O1 q) W' R <init-param>( q; O! i3 ?/ k
<param-name>sessionFactoryBeanName</param-name>6 R8 U# D4 R) o7 N, A) c* N1 }
<param-value>sessionFactory</param-value>6 {8 k; A4 j+ ]7 @( j5 o( ~: ~
</init-param>
4 s5 v9 e$ Z+ C/ S' |" p2 Z% f </filter>4 |$ E3 u3 N1 E9 P
<filter-mapping>
" ~- R% c/ F- M- q: X( }. n( b <filter-name>openSessionInViewFilter</filter-name>" T- V( G. ?# }7 {+ i( @. }' j7 P
<url-pattern>/*</url-pattern>
6 K+ I1 \5 i2 S k( I8 L7 `# S! n8 B </filter-mapping>
B" Q' ~$ t" _+ W1 m9 @. }. d6 s8 i
|
|