该用户从未签到
|
1、创建Web Project ^5 ~2 \: r; z/ l. N1 Z4 o6 f; z
2、web工程与struts2整合
7 |. {" e0 T! W5 p8 ^! [ (1)添加struts2类库
& z0 X* ^1 u6 f' _ J struts2-core-2.1.8.1.jar
- B% k1 i4 D m8 W xwork-core-2.1.6.jar
4 \ D- q+ L' B9 o9 B% E commons-fileupload-1.2.1.jar
1 m" O3 z. P' }7 S commons-io-1.3.2.jar
0 D( J6 l5 s( i! b ognl-2.7.3.jar5 I- H2 \3 A# R( z' U" K4 u# @
freemarker-2.3.15.jar- L2 O3 }3 y' V y
(2) 在web.xml文件中添加struts2集成
& ^/ E! I* B8 }3 }8 Y <filter>
$ a6 Y; w2 P6 v! f9 L <filter-name>struts</filter-name>' ]3 J( P& M/ x: ?/ b+ x" `2 {" w
<filter-class>% S& t C0 e2 x @- I1 I
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter* G% e- J0 ^/ G# R( q
</filter-class>$ q8 O5 [5 \3 Y6 N6 h, ?4 f/ L
<init-param>3 m+ L/ J" C( X4 g" o
<param-name>config</param-name>
/ I; q1 F$ v H! R; |( g <!--
7 T2 a% H" B% R4 o2 T V! H 修改struts2默认配置文件,) O7 P& y+ }0 M7 O
必须把struts-default.xml,/ N6 \* a/ n8 |6 v) n( N
struts-plugin.xml一起添加
$ R K3 T0 A3 z9 A9 t6 n( i8 z& t 必须:按顺序添加7 |. k, Q1 ?) y% M& M) ~
-->
& f! l9 Y# Q; E" N <param-value>
2 Q1 [) ~ E, x5 U struts-default.xml,struts-plugin.xml,config/struts/struts.xml0 |2 S1 X# d2 q8 m' S, f) [$ C
</param-value>2 v" O+ K1 V n8 w3 @+ s
</init-param>/ w7 @; K2 d3 S4 M# J) n" P4 P# w7 P
</filter>
' [6 ~, G9 }; {0 U1 O+ z) T <filter-mapping>' d a: S, t) {. V1 N+ O" ^0 n) c: l5 S
<filter-name>struts</filter-name>
" @3 ~* a5 j* G% }0 k+ r <url-pattern>/*</url-pattern>
1 S* V3 e$ F# n) s T; X; {8 y1 } </filter-mapping>
2 ]2 g* Z- V* X7 [ e- ] <!--struts2 *.action struts2 *.do-->7 H+ T# s) \; k) u4 W
(3)创建struts2配置文件struts.xml配置
2 e' n& U- D7 K5 v8 |* {3 H (4)完成页面跳转* M4 E3 E9 S/ B; f4 U
3、测试struts2工程
0 u2 |% e4 z" p4、struts2与spring集成$ x% p. Z& W9 l
(1)添加spring类库与struts支持spring插件
3 W; J' ~: [4 w# F struts2-spring-plugin-2.1.8.1.jar
@" S9 p( @2 q* y. x cglib-nodep-2.1_3.jar
8 O. u7 k: z* f2 Q. q/ ] commons-logging.jar; ^* w1 R8 s+ A
log4j-1.2.15.jar
7 O. G5 u; U( |2 Z' `5 g spring.jar
6 h7 r' u$ m D) I7 ^# W4 u3 ? dom4j-1.6.1.jar
$ h4 f' \' p0 O! a (2)在web.xml中完成spring集成) W. m9 Y$ r2 ?2 {& K8 w8 T
<listener>
2 S/ [% d8 }& ~/ z <listener-class>
) Y# m3 @; M, J% N% n org.springframework.web.context.ContextLoaderListener8 O4 r# W1 f1 d5 A( _
</listener-class>
) W+ n$ C8 `6 M5 }% N# ?2 _3 R4 R </listener>9 @0 m4 N* s4 \3 F2 j
<context-param>
2 {" O) O( G* U1 i <param-name>contextConfigLocation</param-name>6 b6 g# F, S# i
<param-value>4 N) i# E; z, ?4 Z0 p0 x( V# l$ Z$ ~
classpath:config/spring/applicationContext.xml
3 G; n5 V1 Q) E <!--classpath:config/spring/applicationContext*.xml-->' |+ b- E5 y9 G/ x6 u
</param-value>" R2 _! u" c! \9 x' h
</context-param>
2 x$ U6 e; ?% K# s6 l' c) w (3)创建spring配置文件applicationContext.xml$ b O/ ]; e- r3 v
(4)在struts2配置文件中添加spring 集成常量- p2 ~6 w: S: \
<!-- 设置集成spring框架 -->
( @) F$ ?' y3 q. P3 x <constant name="struts.objectFactory" value="spring"/>. C1 j" \( ?* g6 q9 m% M
(5)spring管理struts2中Action5 G: Z$ g- C1 L' ~
(1)在spring 配置文件中加入bean管理
1 }% s1 k/ O& d, ?! j" J <bean id="userAction" class="com.tarena.web.action.UserAction" >, W# X, n& N: } t
</bean>0 @* M* u i F3 v
(2)修改struts-user.xml配置
, O4 v, x# w) f5 U5 A: H1 e8 m <action class="userAction" >
& p8 q" R, ^9 K. d/ K6 w </action>
1 L9 u0 C2 G3 y. F5 测试struts+spring集成
7 k8 M" ?, _, i+ N6 T; Q, w6 spring+hibernate集成
. a4 M. \# e! p. l (1)添加hibernate类库
' R+ O/ T3 ~; V. x4 O$ D& V slf4j-nop-1.5.8.jar
* u) z* F: W) Z! N, V slf4j-api-1.5.8.jar x! q# E; r) y
jta-1.1.jar
6 r, F, B2 B, e& ?& F# e* b javassist-3.9.0.GA.jar
, @; I- }) g, n hibernate3.jar% ~! a- L4 k$ O) u/ w
commons-collections-3.1.jar Y2 G8 H/ \& N: l! K1 ]
antlr-2.7.6.jar
2 d. `2 R/ C1 J7 w8 @ F (2)添加MySQL驱动类库
& Z; B1 Y( {8 v$ U4 d% N' A7 u mysql-connector-java-5.1.16-bin.jar
% Z4 `% D6 L8 d( \" }. l, D (3)创建实体类 j' d3 K, l* p6 P2 d
(4)编写User.hbm.xml映射文件) E. t8 G% F1 O U5 J2 U% x( M
(5)反向生成表结构
( |7 U! E3 y6 [) r3 H$ w) [9 N (6)spring管理hibernate
; V2 F) ^: `9 O8 `- c0 } 在spring applicationContext.xml配置文件中添加spring对hibernate管理
7 _! {. C: n3 K9 i8 U, a d (A) 添加DBCP连接池
7 E; `# B. W V a、添加类库1 I- J, d7 i/ d) Y
commons-dbcp.jar9 a- l3 z; Q5 d1 j& q2 \
commons-pool.jar
. F2 E% L3 x% w8 }0 f8 c8 O- h% d b、applicationContext.xml在配置连接池2 Z* Y' l! D! ?) f
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> s9 \1 J6 f, y4 o
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>% u. ^9 ?9 W8 T3 k0 ?
<property name="url" value="jdbc:mysql://127.0.0.1:3306/mydb"/>* T1 |- h8 p- ]: B
<property name="username" value="root"/>; C% y2 c7 Y) F# ]& q# g! H
<property name="password" value="1234"/>
) N& G3 k3 }" [9 T; ~# x5 Z6 w( [ <property name="initialSize" value="2"/>
9 w" z! G8 N( `' w" S9 Y( c( s. a <property name="maxActive" value="8"/>
3 m3 c9 |' y! I9 |1 j+ `! W* m2 t <property name="maxIdle" value="5"/>& r+ I2 J0 K5 [/ ^
<property name="minIdle" value="3"/>
' W2 P8 B1 D, s- ]% G, w8 \* a <property name="maxWait" value="3000"/>" O, B' |( _4 M+ n: J) l
<property name="removeAbandonedTimeout" value="60000"/>
! ]7 Q. `1 e$ N9 W <property name="removeAbandoned" value="true"/>
1 e, V+ ? s% |' q2 M7 d </bean>! o' w. n$ Z, w; [* O9 M
连接池参数如下:
6 _# C- b+ M/ U5 u initialSize/ Q6 o8 ~1 R6 h3 {1 i$ o
连接池启动时创建的初始化连接数量
; ?6 C9 {! W/ Y, \% T2 I9 D (默认值initialSize :连接池启动时# o" H5 \2 p0 ` \: \( \' B( Z, j
创建的初始化连接数量(默认值为0) 6 w4 H0 |, Y% r. `. }5 w
maxActive * u% o M) F2 V) t4 e
连接池中可同时连接的最大的连接数
2 R' M' e ]1 F* l+ c7 D (默认值为8 ,调整为20,高峰单机器在20并发左右,
+ c% A; A1 w& P& d/ n 自己根据应用场景定) # L1 F, r+ [5 v
maxIdle8 Q! L* a, ^2 u: t* `& c
连接池中最大的空闲的连接数,
3 g" W7 V2 C, q* l- C9 ~* h4 Z 超过的空闲连接将被释放,
! R6 h' J! A+ J" _, k 如果设置为负数表示 不限制(默认为8个)/ r e6 T. ?/ {4 J3 k6 T
minIdle! G$ t9 w/ l% j5 \
连接池 中最小的空闲的连接数,低于这个数量会被
" t/ ^# N) h4 p+ E$ e; r% O& ` 创建新的连接(默认为0,调整为5, 该参数越接近9 i0 q/ Z& N B N1 T9 x" ^/ p
maxIdle,性能越好,因为连接的创建和销毁,# G# y$ i! v4 ?/ B1 A
都是需要消耗资源的,但是不能太大,
6 m- }5 i3 `9 _2 { 因为在机器很空闲的时候,也会创建低于
3 |8 Z* K P8 B! D8 ^) r+ E1 y minidle个数的连接) . o# E4 b8 U% _+ S) @8 S+ k) F
maxWait ; N- S8 O9 I* z, N9 E
最大等待时间,当没有可用 连接时,
2 _! ~9 {: c4 T7 _2 H* f5 Q 连接池等待连接释放的最大时间,7 a8 @- _/ E' g) ` {# Z
超过该时间限制会抛出异常,1 k$ q. R2 d/ J" D7 J
如果设 置-1表示无限等待(
, ?% F2 s: g. d* j' x) @ 默认为无限,调整为60000ms,
. D' n& S( f0 }$ m$ h- r9 O$ r 避免因线程池不够用,而导致 请求被无限制挂起) 9 c* @! ]" D' {' ^/ z
removeAbandonedTimeout :
1 G6 e3 z# C# R$ t7 E: ]% d 超过时间限制,回收没有用(废弃)的连接 ( i. O: d4 I w
(默认为 300秒,调整为180)
7 P5 I. s! P1 C m- L removeAbandoned :
# b( ~6 L. P" {9 c; b: m 超过 removeAbandonedTimeout时间后,6 R$ C ]! f! q6 s& g0 E! s
是否进行没用连接(废弃)的回收# W) H$ E- f7 J0 |9 Y7 {3 }
(默认为 false,调整为true)
3 x/ Y1 }5 {9 i (B)spring管理hibernate实体映射文件:3 Q5 c- b" B5 [1 Y! d; u
<bean id="sessionFactory"
2 H3 m* W& s& o1 U5 d" z class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">5 a3 E( ^6 ~4 P% M9 {
<property name="dataSource" ref="dataSource" />
: a# H+ x2 \% X# ]! k <property name="hibernateProperties">
o4 n3 `; k) F' r <props>
* L5 ?6 [$ U @3 Z <prop key="hibernate.dialect">* X& B! r; K. T7 Y
org.hibernate.dialect.MySQLDialect" ~. F4 F8 r" N% } }1 j; k
</prop>
' v2 Y% @/ m2 k# Q' r <prop key="hibernate.show_sql">true</prop>7 R2 `7 y* @' D3 Y- U P
<prop key="hibernate.format_sql">true</prop>
U5 Y& W& r+ b: w0 b0 w </props>) g* y+ x2 u1 M* v' [6 k$ ?
</property>
* W( x4 r1 a( b* O <property name="mappingLocations">8 f4 d+ M: D% B. n# d& o% P
<list>
5 V% [1 r; ?5 X1 O; Z <value>, X3 B4 Q" g% t% \( Y: Z3 R
classpath:config/hibernate/hbm/User.hbm.xml
7 | g8 A5 o( \3 M3 Z* B% f3 g: i </value>3 A/ L. o* B8 z! b- c! p' f: q
</list> H1 d0 r: T$ x" @7 [ H
</property>
( [6 a) E3 |& p: ?2 m4 A </bean>6 U) e3 b6 X+ ~) o p% S6 N6 K1 x
(C)spring读写属性(properties)文件$ z/ v# @! Z/ k, P& j- K" A( W% m9 d2 g
a、创建属性文件 db.properties
( C5 o& L5 v& h/ z( }6 N0 } b、在applicationContext.xml配置! z2 u; c' O0 U! z0 T) B
<bean id="propertyPlaceholderConfigurer"! d1 m1 t& `: T6 S8 \
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">4 @3 S& ]" \+ I3 ]! j1 l
<property name="locations">! O; t: S3 \3 a ^( Q; W
<list>6 h! m: v% s: K( k
<value>classpath:config/props/db.properties</value>2 H. C, M: x/ h9 Y! o
</list>
4 B' p( Q: U2 R </property>
9 H, ]1 \' O4 p' K+ A- s' l0 I </bean>
5 @: U/ j/ I8 m+ K. o" ~: P c:引用: ${username}: E: ~1 Y0 W& c& S6 D
. q. O2 F; t& [+ _& J& }
(8)spring分文件管理! i4 p A' N! M& z; m+ E! ~# l% I
<!-- 引入其他spring 配置文件 -->! f% f) J2 [# @) G& {" X& I: r v
applicationContext.xml引入下列文件
1 d! y) ~5 ^% ^$ ]7 f, b <import resource="applicationContext-web.xml"/>
: A4 y) w# I. P% i- n& t9 I& T8 ^9 H <import resource="applicationContext-biz.xml"/>7 x7 m9 [% L" w6 }
<import resource="applicationContext-dao.xml"/>
* o+ W# l) _- ?/ F- W9 q7、开发数据访问层: N" `4 g1 l7 Z( J" k. O0 L
使用spring提供hibernate 模板类 HibernateDaoSupport
1 [+ t1 |/ i+ T+ F* E3 z/ Z UserDaoImpl extends HibernateDaoSupport
K# T$ R) D' i+ _6 L. { 在UserDaoImpl注入到spring 配置文件 applicationContext-dao.xml
9 q$ H4 R0 J& t; f <bean id="userDaoImpl" class="com.tarena.dao.impl.UserDaoImpl">7 d6 \! J5 e: \9 `! j" [) ^0 H
<!--HibernateDaoSupport中的sessionFactory-->7 ?6 w' z7 i2 {" f
<property name="sessionFactory" ref="sessionFactory" />
; Y, Y& }8 a8 g" E* z1 ^0 c3 Q9 k6 n </bean>
. k+ y8 J# a0 y$ e8、添加spring声明事务管理(AOP)
# v \& V; E/ H1 t6 W8 ` R) ` 声明式事务管理:
3 W# `) ^, q7 D% V2 @ 添加spring 类库$ L$ P9 |9 J3 O4 s: [: |* T
aspectjrt.jar
) k( x+ H& ]0 H8 [3 x$ a aspectjweaver.jar
8 H' C9 M. r. i& u9 ]$ p 了解事务的几种传播特性0 B6 U! [' c* _# H( d
( L" p6 U3 _ l( _$ t
(1)PROPAGATION_REQUIRED:
7 o6 q8 i+ q) q8 a5 ^ 如果存在一个事务,则支持当前事务,如果没有事务则开启。
# @3 W# Z( N* z6 i% M0 u, p: s (2)PROPAGATION_SUPPORTS:
4 l: }/ {8 Z$ z! z% E2 ? 如果存在一个事务,支持当前事务。% s! P# F# s1 F9 ~9 \+ ~
如果没有事务,则非事务的执行。+ s8 u0 `1 Z% x2 K. a
(3)PROPAGATION_MANDATORY: 3 S7 h: c4 O0 e" m. g7 N7 O
如果已经存在一个事务,支持当前事务。. [& e/ C. J! Y+ Y! e
如果没有一个活动的事务,则抛出异常。
+ p2 s! O8 F0 }: c% r (4)PROPAGATION_REQUIRES_NEW:
5 ^) }" P0 E+ z2 Q7 K O 总是开启一个新的事务。如果一个事务已经存在,7 Y, p% q3 j8 k* d; Q
则将这个存在的事务挂起。8 o$ C4 s5 s; ^4 y( Y0 K7 D
(7)PROPAGATION_NESTED:(spring特有) {1 E# W6 K G0 [& e! I5 {
如果一个活动的事务存在,则运行在一个嵌套的事务中.
6 }& n* ]4 E1 d, ^+ e/ m 如果没有活动事务, 则按TransactionDefinition.
) C# P! P: m4 h1 {7 M PROPAGATION_REQUIRED 属性执行
. D2 ^5 s% x9 i
9 g1 E4 X4 Z7 d" a# o (5)PROPAGATION_NOT_SUPPORTED: 2 j0 ?1 Z$ L. a# u6 O
总是非事务地执行,并挂起任何存在的事务。
/ F. c+ R& p8 y8 _: [2 Y: I (6)PROPAGATION_NEVER:
" `; N( H( h, c# j4 v) u$ L* ^ 总是非事务地执行,如果存在一个活动事务,则抛出异常。
* q% R/ H; W# c; o9 T6 i" R$ @; {3 N) R) G4 A
9 ?; a6 ?2 f1 M) D. G. C! u5 z <!-- 配置声明事务管理 spring2.x-->; M# z0 i3 Z, F5 D; D) _1 ~0 f
<!-- 定义事务管理 -->
0 g8 f, P8 g$ \* h; D; F( x) l <bean id="transactionManager"
/ R8 I! T, ^4 d6 G8 |) F class="org.springframework.orm.hibernate3.HibernateTransactionManager">
3 O, o! v3 H$ m- V- z! o <property name="sessionFactory" ref="sessionFactory" />; l. t& U2 n4 |7 C' l
</bean>+ M2 K y! w' ]4 X$ o
<!-- 事务规则 -->: W; p" u; ?( c/ Q
<tx:advice id="tmAdvice" transaction-manager="transactionManager">
9 A" j1 |) L0 j9 M <tx:attributes>
! S) T5 e2 w0 y <!--*通配符 save* 方法名必须是以save开始-->
6 i* S1 ]$ s7 ?6 X <tx:method name="save*" propagation="REQUIRED" />
2 q9 J" D( y, F! O9 R <tx:method name="update*" propagation="REQUIRED" />
) I4 h" d( g- z' d' q0 K2 a <tx:method name="delete*" propagation="REQUIRED" />
& U l! [3 Q: T7 m" c! X <tx:method name="find*" read-only="true" />
$ z( C/ I: M* R" x( k4 K D <!-- read-only 只读:-->1 i8 Z$ Z9 f6 i$ }
</tx:attributes>
$ E6 e; H# C2 t/ r! p4 D </tx:advice> r& ^: L1 h+ I3 b4 c% S
<aop:config>$ P" {" z3 d+ f# w
<!-- point cut -->
" D. [, Y d! o3 C <aop:pointcut id="pointCut"- g. T8 V( w8 |/ Y D
expression="execution(* com.tarena.biz.*.*(..))" />
; n% o8 X1 P. |$ \8 } <aop:advisor advice-ref="tmAdvice" pointcut-ref="pointCut"/>
2 {5 K/ {1 |! J3 O8 a, e$ S+ g& r; F </aop:config>5 {/ m- `) G& T7 g' H2 m5 Q
# U3 ^2 _+ {! C) g
9、测试 A/ ^: q+ ?2 e; p# w
添加测试类库 spring2.5.6
- U# D& R; ?7 E+ ]. m9 |" l% \: @ junit-4.4.jar9 b# u+ A/ T _2 x/ u& G+ S+ S
spring-test.jar4 y( c; S$ W4 F
//使用spring测试; C% A* H! R# k1 X
@RunWith(SpringJUnit4ClassRunner.class)
) l" f- h \; v2 q' n //加载spring配置文件
& C8 s2 S/ ~ n9 g8 i @ContextConfiguration(locations = {
! w4 v& r( S. k5 F9 ^, \8 Y5 v5 J "classpath:config/spring/applicationContext.xml",' F8 [- G n" u1 `) H$ Q
"classpath:config/spring/applicationContext-dao.xml",
( ~* G- I/ C7 _. ` "classpath:config/spring/applicationContext-biz.xml",, Z; [2 f* r* K6 _
"classpath:config/spring/applicationContext-web.xml" })
0 f/ K* l6 C7 ]/ f1 U5 | //自动注入: L6 K+ ?5 d+ i! ~2 V: d* j9 S
@Autowired, r; M! ?0 \ Z
private IUserDao iuserDao;8 I& q6 g3 y. r+ |6 N+ ^8 W
- l% h% W4 `3 N* I+ F5 ^ @Test* w2 `! \; u/ E+ ]
public void saveUserTest(){
r( ^; \: e: c9 c! E4 q //测试方法
3 |) I; C' ]6 U0 W2 m. Q0 { }
- \( R1 g2 }3 A' n& Z" d10、完成业务层代码编写
6 l/ c% X2 w2 G* v/ C+ I11、完成表示层代码编写
1 k Y& ~9 P& O5 \( L' T+ k12、测试工程# n% I0 L7 M3 ?8 q8 C# x. x
4 M N/ n, }; v0 Y# B" Z2 {6 e% ^
13、spring处理hibernate延时加载+ [* B* \' U; o( Q9 V7 q- |
1、配置延时过滤器
8 i9 @/ S* Q" n3 N) z V, o% ~ OpenSessionInViewFilter.class
( R4 C9 ?4 R I3 A* |" [: J5 F( g& l2 L9 U 2、在web.xml配置OpenSessionInViewFilter" E6 @+ G8 D; V0 i
$ y9 E' L$ h7 f' V# r+ [ <filter>" V" c; p. x4 d
<filter-name>openSessionInViewFilter</filter-name>
8 v$ o0 [" A2 M, ^2 w6 Y ]6 q <filter-class>
. B: @/ w: Z; v1 G6 M! k2 y3 G org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
) e6 K9 n8 l7 J2 Y, G# e. u2 M </filter-class>
2 H$ l4 P4 ^* U7 M V: v: Q$ M. C <init-param>
/ @1 f, p9 ^$ n <param-name>sessionFactoryBeanName</param-name>
0 c* P4 j) D3 L1 f" f& } <param-value>sessionFactory</param-value>
! ]& m3 X! d( d1 S0 ?+ j5 C, K </init-param>% H7 \% f7 d9 F d0 n7 ^
</filter>$ B: X* P6 o7 r. W' `/ t8 w
<filter-mapping>
' E3 b" y, k4 f9 ]1 s1 w8 d: K: X <filter-name>openSessionInViewFilter</filter-name>
2 a% t5 t7 L2 f1 j9 e <url-pattern>/*</url-pattern>2 ~# \: U8 c$ Q9 I* P# O
</filter-mapping>$ u) h' L0 L T" k
1 b3 x. d3 S3 C4 ~/ P |
|