该用户从未签到
|
1、创建Web Project
" E+ q2 s5 R- [, h- |# x2、web工程与struts2整合% Y8 u: Q1 r, t4 n# w8 c
(1)添加struts2类库
! t9 H4 n, B n5 W! i+ W& u struts2-core-2.1.8.1.jar
0 e- s2 ?7 `4 ` xwork-core-2.1.6.jar
0 \8 Y* c. s" J9 L& J- J& n commons-fileupload-1.2.1.jar( c- t' x& h0 ~6 T+ w1 ~4 d M
commons-io-1.3.2.jar
0 j9 j. {4 o( Z) o% t& M ognl-2.7.3.jar
" w$ `' |% W# A3 a3 f6 Y$ T freemarker-2.3.15.jar
" r$ Q8 t% X6 M6 k3 n/ s' d' G* ` (2) 在web.xml文件中添加struts2集成
- T: }; k; K+ W3 p9 k <filter>$ D& w) k% P" O3 S# W/ K% A. i
<filter-name>struts</filter-name>
) b' |' t( R) W2 r/ M, h <filter-class>4 ^" a: @ J$ N* j4 ]1 X5 p
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
: l- ~6 D4 y' M r3 l! i0 C C; o: q </filter-class>" S6 q+ ]' F( u- e' N/ D
<init-param>* w6 s" Z' W( P( E& l9 E) }1 x
<param-name>config</param-name># ^2 U* m" R* q. P+ Z9 F
<!--
% E; }7 u y& R+ O1 j) g3 L8 N& k- o 修改struts2默认配置文件,
1 S, B" D- s* Q9 X7 n. A. ~3 w 必须把struts-default.xml,
6 j$ p* g* j o9 `) t struts-plugin.xml一起添加; E. l6 f9 U7 T. {8 Z& k+ e
必须:按顺序添加. v# @' u& {- r6 f, y
-->: D: S7 M- ^& `3 `" V4 A
<param-value>
- R+ q7 Q* X$ z3 B( G3 { struts-default.xml,struts-plugin.xml,config/struts/struts.xml9 W& v; O% [+ H6 l; }; N. e
</param-value>- | J2 w% l: b: {$ [
</init-param>0 m( \4 B9 q b
</filter>& n3 s3 [3 ]0 o) k% R8 j
<filter-mapping>7 j0 Z w, m6 f
<filter-name>struts</filter-name>5 O. m0 J: `& m! l
<url-pattern>/*</url-pattern>' H4 D0 }$ o. q I, R1 Z
</filter-mapping>
t \# ^8 H# U9 l& ], @ <!--struts2 *.action struts2 *.do--># ]" X1 _) G! e1 I
(3)创建struts2配置文件struts.xml配置 / L# u k/ v. h. @" p" l
(4)完成页面跳转
( }1 C( V2 c5 E2 ]& W8 F7 S- k# Q3、测试struts2工程
3 x0 J. X* ~8 [; d' y$ j2 N4、struts2与spring集成% u4 c6 C/ C# k: f/ H9 V
(1)添加spring类库与struts支持spring插件 B& q7 H/ f$ @- F! X
struts2-spring-plugin-2.1.8.1.jar& v. s* \8 z' o- B5 ] B" I" J
cglib-nodep-2.1_3.jar
7 G* {2 M9 [7 d I! \& u5 ? t* o commons-logging.jar/ ]: P; Q( x3 T% H0 E
log4j-1.2.15.jar
& x+ Y$ z& Q% T3 i2 Y/ V spring.jar. h3 U( V5 n( g4 X2 p
dom4j-1.6.1.jar
; S) l W" i. {* t* i (2)在web.xml中完成spring集成; ]7 a& l9 B5 g( B7 v- W7 j5 l5 |
<listener>
" Z# N" ]& u7 Q- A& ^. V n, B <listener-class>
+ p! c; H4 }0 p/ O2 k a0 P org.springframework.web.context.ContextLoaderListener
. C* a; K! b8 u% ~ </listener-class>
# ?+ S0 S" q) d* V# M </listener>
$ u% P/ A( I6 O8 u5 S. | <context-param>- d0 U$ o" L( T6 n0 m
<param-name>contextConfigLocation</param-name>; d& ]/ f8 j e2 B9 M/ W- S( }% F
<param-value>
" p. }9 ^2 V. E5 M, i l- t, c classpath:config/spring/applicationContext.xml
% G, x7 C5 ~& x3 `- L <!--classpath:config/spring/applicationContext*.xml-->
$ v0 I& {0 _/ a7 x& c3 f </param-value>
$ C9 a# @" Z( v) I* Z2 M </context-param>
2 G8 Z: w b5 r4 s) l( e6 W. L (3)创建spring配置文件applicationContext.xml
& p1 ]5 T6 a3 ^1 j5 f" V (4)在struts2配置文件中添加spring 集成常量
- z* Z% p% [- G4 M <!-- 设置集成spring框架 -->
\2 l! I2 q7 A. C <constant name="struts.objectFactory" value="spring"/>
3 P7 [9 f G N2 n' ~% n4 D" ^( y/ s (5)spring管理struts2中Action; b6 E+ `2 | M3 M- b
(1)在spring 配置文件中加入bean管理
7 a9 {; @& i5 T4 X) k <bean id="userAction" class="com.tarena.web.action.UserAction" >2 z' V3 n" y8 V5 f- }* e* T
</bean>
7 N% K4 ?! m" f) e" F4 H5 L (2)修改struts-user.xml配置
& j! V" ?1 T L5 V' J7 a* k0 ` <action class="userAction" >, [! Y7 q: i5 f% P; ?& l3 S6 w- S; N4 y
</action>
" l" N ?! V, V* u4 }' a7 E7 h5 测试struts+spring集成
/ z# |. o0 H2 o% p6 v6 y6 spring+hibernate集成
`& q) l: |& z/ K6 P (1)添加hibernate类库
2 S/ W5 f2 `; M2 K | slf4j-nop-1.5.8.jar. u' X; B y7 d& H
slf4j-api-1.5.8.jar5 S9 ]+ d; a9 D; ~% m. _
jta-1.1.jar0 ^/ V" o0 e! P/ [1 j
javassist-3.9.0.GA.jar
- p3 s4 ?3 W. y# D" C8 B hibernate3.jar
/ t) `" W# m! h! D; ^ commons-collections-3.1.jar- b5 t& k* s8 R9 v* o& Q2 Q1 r
antlr-2.7.6.jar7 G. ]- W4 t G* x9 c, @- [
(2)添加MySQL驱动类库
2 V* l' a4 w! } j mysql-connector-java-5.1.16-bin.jar1 x, @) c" s$ c; b3 S
(3)创建实体类
l; L2 J! z* i8 e2 f3 h& S (4)编写User.hbm.xml映射文件
. s$ T' Y, ^ D2 |8 f M# h! Q (5)反向生成表结构4 h* u( z6 a9 {" X# [
(6)spring管理hibernate % z7 w/ W# k+ A% q" c" t4 R
在spring applicationContext.xml配置文件中添加spring对hibernate管理4 L" w) ~$ I3 m y0 z* h6 G( ?
(A) 添加DBCP连接池
& I4 [ k/ f8 A$ {, N+ h' I a、添加类库
* k+ f t# g6 K: i# ] commons-dbcp.jar
+ Y4 _/ S9 M& \, G; O) s3 C commons-pool.jar2 R/ W. U+ `- a5 q
b、applicationContext.xml在配置连接池2 }/ t H9 K4 N3 E
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
, v: s* a5 i6 q' S$ n$ W' O <property name="driverClassName" value="com.mysql.jdbc.Driver"/>7 p" c) [) O. _: \; k
<property name="url" value="jdbc:mysql://127.0.0.1:3306/mydb"/> J/ v- o6 g4 x/ N5 m% y" ~
<property name="username" value="root"/>' B+ M \/ {# ~
<property name="password" value="1234"/>% H& x# w: ?& F$ C3 ~+ q- W! u
<property name="initialSize" value="2"/>
6 t1 f2 v& X: }& E( [# a <property name="maxActive" value="8"/>
% z' n8 x# `: k" b <property name="maxIdle" value="5"/>
; j& o- `7 i- F8 q1 R4 ` k <property name="minIdle" value="3"/>: |5 R% W T% D: D' u2 T- ^
<property name="maxWait" value="3000"/>8 `# F1 {- d5 x! S/ I' U
<property name="removeAbandonedTimeout" value="60000"/>: r$ ~% ?2 E0 F8 J; j0 r6 y
<property name="removeAbandoned" value="true"/>
5 s3 U( {( E2 \, ` </bean>
/ |& H$ p; t @. S) }- E 连接池参数如下:
: s' }- z+ l, T( |4 j initialSize; H, H# O3 l0 Y; J
连接池启动时创建的初始化连接数量
3 I( S, C" C7 ?: N6 N& M: N( X (默认值initialSize :连接池启动时
% e2 z/ [$ |% y) i* f 创建的初始化连接数量(默认值为0) 3 t; t8 E; C* [- b6 k. Y
maxActive
" d: T5 o. e( L* ?! S 连接池中可同时连接的最大的连接数; g1 m% J' _- }7 d
(默认值为8 ,调整为20,高峰单机器在20并发左右,
4 M- B6 l& @( x5 L4 t 自己根据应用场景定)
' Y' K4 A5 Q( ^& {) ]! k7 S maxIdle) J4 H0 {) Q" w' {
连接池中最大的空闲的连接数,
- m5 N) t- Q. p 超过的空闲连接将被释放,
h, |' T7 S) Q6 J' G6 ^ 如果设置为负数表示 不限制(默认为8个)9 K6 v, @0 x5 M, y
minIdle
# f7 G' v" H1 r0 j, _5 _" T 连接池 中最小的空闲的连接数,低于这个数量会被
, A5 K2 G5 f L 创建新的连接(默认为0,调整为5, 该参数越接近" @% ?0 f: o+ m$ L
maxIdle,性能越好,因为连接的创建和销毁,
1 n3 E4 @% ]7 _! ]6 \3 f" V: B 都是需要消耗资源的,但是不能太大,
' c2 f; c# c& s, M C: q$ [+ h) B3 ^9 w6 b 因为在机器很空闲的时候,也会创建低于: P* M9 }6 A& ~9 y) Z# i
minidle个数的连接)
, a2 F: Y5 F' c maxWait
K: ^, O. W* x2 Z 最大等待时间,当没有可用 连接时,
: I- M8 W1 D3 r1 P+ M, J, |. e 连接池等待连接释放的最大时间,
# y1 o B2 ~! J/ ?: i9 V$ { 超过该时间限制会抛出异常, V! C. Z; X8 C4 p, \5 r
如果设 置-1表示无限等待(
2 u% |, y* T% m) W4 Z, J3 p8 h 默认为无限,调整为60000ms,
& [! W3 l" d2 J0 b' c3 q 避免因线程池不够用,而导致 请求被无限制挂起)
2 M- A, f7 h; s8 A removeAbandonedTimeout :0 x& P% w1 D" }4 {+ Q/ V
超过时间限制,回收没有用(废弃)的连接 ) v+ U$ f) |6 A4 W; Q
(默认为 300秒,调整为180)
* x) E; M! S8 I; R' u removeAbandoned :
0 l* j( e4 R1 ]. `* P 超过 removeAbandonedTimeout时间后,$ a/ R, j4 D9 V
是否进行没用连接(废弃)的回收$ V, z& d( r/ f5 y" I$ g# R6 {/ b
(默认为 false,调整为true)
+ Z0 q: H8 T# x0 u/ q& n* `3 M (B)spring管理hibernate实体映射文件:
5 q: V% M. [, M R) E <bean id="sessionFactory"
0 A1 q \; r$ N% t7 r class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">! C- \( E( l* W. Z3 M5 u
<property name="dataSource" ref="dataSource" />
+ c" B, {# w+ G; i/ B <property name="hibernateProperties">
+ N( _3 _" C& N3 |2 m3 e <props>
5 Q* d$ h, i- k( I, T <prop key="hibernate.dialect">
0 ^4 Y( Y" ~: p g4 n- n org.hibernate.dialect.MySQLDialect0 t3 F V& u2 h ^9 T
</prop>: F. [: u" R0 \+ E
<prop key="hibernate.show_sql">true</prop>
! I8 U3 H3 X9 T0 m2 M3 k0 J T2 v3 Q <prop key="hibernate.format_sql">true</prop>
% |! [8 K2 E0 g6 m! }$ I! ` </props>" J! Z) E. S8 ]
</property>! M- s( @6 l, E- h) w7 Y
<property name="mappingLocations">
2 r: q0 a* t2 G! e% X# g" y! G <list>
' W9 o3 H. q# g <value>
. @8 @/ K. o& d# u" E( f* r/ d6 g classpath:config/hibernate/hbm/User.hbm.xml
+ Q* @$ A: w5 _' M8 U4 y2 ? </value>" G0 u6 V- v" I# o$ R5 k
</list>
: n% Z2 a% Z( g- u </property>8 K9 j1 e& u) j1 P; ~3 w4 E
</bean>
* H3 z/ J: z( G U" u (C)spring读写属性(properties)文件7 W4 b& c$ M( ?6 N* O. Z
a、创建属性文件 db.properties
, M2 u- c( M2 s9 a7 k. T b、在applicationContext.xml配置2 n( T6 y! v9 a
<bean id="propertyPlaceholderConfigurer"1 M& P6 x1 _! q" K" W5 V
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">2 C" E8 B4 W* _9 E& e$ F& E4 O7 O" j
<property name="locations">( F4 s, C5 f I4 s2 h N9 H
<list>
4 h0 Q6 {# r: X3 l1 |: O <value>classpath:config/props/db.properties</value>0 h, ^4 k$ u; }
</list>
p& i) J7 }) Z9 N </property>
, y: v) |7 @2 x; q2 ]! ^ </bean>
) L7 C8 W$ A0 z: K' `/ ? c:引用: ${username}
& k! ]! h/ d# y$ {. O' b - @7 X" ~1 G8 P5 _5 v* R# ^
(8)spring分文件管理
) J- ]/ S3 d E+ Q$ C" L6 f <!-- 引入其他spring 配置文件 -->
! R, R. m4 w, g' f) o- ^1 I6 E+ a applicationContext.xml引入下列文件
# ^% q# P" B2 R9 ]; X% D <import resource="applicationContext-web.xml"/>
# O1 C M w9 f9 { <import resource="applicationContext-biz.xml"/>
" f9 h% i- n0 n! P0 e7 L, s7 M5 j <import resource="applicationContext-dao.xml"/>7 A) z/ `: q, ~3 S5 v+ T8 H
7、开发数据访问层
- y) h- a4 y' H6 R 使用spring提供hibernate 模板类 HibernateDaoSupport
+ p& L6 E% `! j6 |9 Q5 L5 D UserDaoImpl extends HibernateDaoSupport# w0 d. @6 c' U) h: }! z
在UserDaoImpl注入到spring 配置文件 applicationContext-dao.xml
7 M4 g7 ?& J: w5 X& |* c; {0 h <bean id="userDaoImpl" class="com.tarena.dao.impl.UserDaoImpl">
6 q2 ], G& y+ m" Z/ W+ n <!--HibernateDaoSupport中的sessionFactory-->: _" X3 g# n3 U4 }7 a) g
<property name="sessionFactory" ref="sessionFactory" />7 @/ }1 V4 h+ ?! s5 M
</bean>8 L8 N* ]/ A% r6 ^/ i6 |
8、添加spring声明事务管理(AOP)
9 s$ D5 j4 B6 ?; M9 E 声明式事务管理:$ o! N7 b8 x3 T V
添加spring 类库9 e7 l' l: ~6 _, a5 x& x; [. V
aspectjrt.jar9 N- i2 D2 b6 z# q3 m4 P7 |
aspectjweaver.jar3 b+ A2 t% v, Q6 c4 ?6 t
了解事务的几种传播特性2 C! o5 s% H" Z A3 h3 [
; x4 h( ?% N3 G; \ P9 T; [+ v
(1)PROPAGATION_REQUIRED: 5 A$ `- s V7 U/ c7 t+ e4 \$ W
如果存在一个事务,则支持当前事务,如果没有事务则开启。8 G" Z& b- r) J6 z" `9 G
(2)PROPAGATION_SUPPORTS:
4 G1 Z9 I5 r# K6 A 如果存在一个事务,支持当前事务。
" U, m x: D$ s3 g6 L+ R" g1 U3 M9 @ 如果没有事务,则非事务的执行。
7 Q' m# r7 c2 m0 x6 _2 L+ t2 V: Z (3)PROPAGATION_MANDATORY:
! ^6 w+ ?1 X7 N1 ? 如果已经存在一个事务,支持当前事务。
6 ?; [4 A# @/ d i# r 如果没有一个活动的事务,则抛出异常。. N) ~# T( l3 d7 [( e( i% b
(4)PROPAGATION_REQUIRES_NEW:
, r3 W4 O6 v; G5 H 总是开启一个新的事务。如果一个事务已经存在,
/ p+ r5 H7 f3 A: t 则将这个存在的事务挂起。
8 B# Y8 b& H" S( N$ K; T (7)PROPAGATION_NESTED:(spring特有)
6 u, C5 ~+ D8 l& W% @! ~, S 如果一个活动的事务存在,则运行在一个嵌套的事务中.
# C7 W [) B% J) Y% f( ~6 T 如果没有活动事务, 则按TransactionDefinition.3 Z! n9 V8 @# N- o
PROPAGATION_REQUIRED 属性执行
$ Z8 U8 }% o2 s7 x3 p' v* o- E ~* C) M& D, ~. Z! Y! V
(5)PROPAGATION_NOT_SUPPORTED:
q- n4 m( e/ N 总是非事务地执行,并挂起任何存在的事务。; @7 G6 x# r9 f" J) l' f" f
(6)PROPAGATION_NEVER: + {; I, \# Z) H* B c, T
总是非事务地执行,如果存在一个活动事务,则抛出异常。
7 B; u( }. l6 o2 \) I# G
! s; }! S( `: b" W+ [# V 2 M7 c! W+ n( h- I( \( T3 Z
<!-- 配置声明事务管理 spring2.x-->
1 l R7 v/ I' U6 Q! t4 e% e <!-- 定义事务管理 -->
& @) U9 ^5 j8 Y6 x+ y <bean id="transactionManager"
5 p* C4 p$ W5 Y' P; c; J) K class="org.springframework.orm.hibernate3.HibernateTransactionManager">* a; m0 s% k7 \+ U% S) ?
<property name="sessionFactory" ref="sessionFactory" />
+ E6 E( O6 B- a6 z) s </bean>
0 U% X( u3 g1 Y8 F <!-- 事务规则 -->
# m" J, H" |1 A& E <tx:advice id="tmAdvice" transaction-manager="transactionManager">2 ^1 S; M9 E2 V+ U
<tx:attributes>% [* w: K! b" M' ^
<!--*通配符 save* 方法名必须是以save开始-->. n8 n8 N. K8 [) t" O
<tx:method name="save*" propagation="REQUIRED" />
4 N9 Y# z0 a2 L; M0 G <tx:method name="update*" propagation="REQUIRED" />' n/ p; I2 H, B0 J Z3 @8 u" e: j9 M; @
<tx:method name="delete*" propagation="REQUIRED" />0 R& f k, z, ~( ?( G6 b E
<tx:method name="find*" read-only="true" />. e3 n) K' k) Q4 J% B2 k
<!-- read-only 只读:-->/ L) T* J0 `" ]$ d5 i, s
</tx:attributes>
$ H/ u! Q: o5 d) R2 Z1 f8 l: K% l$ | </tx:advice>
: k, y! Q' u. s; _/ D8 k& ]6 ^ <aop:config>
: j% w7 V" C) m1 U8 h/ H- q( }1 o <!-- point cut -->. X5 L/ I1 a r; ~9 Y4 B5 k. O
<aop:pointcut id="pointCut"
8 J5 `9 q: R2 f( S, o) ~! x- ~ expression="execution(* com.tarena.biz.*.*(..))" />& m+ J, H3 Y$ _
<aop:advisor advice-ref="tmAdvice" pointcut-ref="pointCut"/> & W0 X7 w) f6 ], h
</aop:config>8 d4 }: P. s' k8 S4 I
( q, n, r4 V/ d# i, S
9、测试
3 y* B+ k1 p. \7 `7 a+ C$ I% h, H E, l' G 添加测试类库 spring2.5.6
/ Q1 {' D8 X) v1 U& p( i1 Z2 I3 l junit-4.4.jar
; v& E" _$ ^2 R* [ ~4 q, j spring-test.jar
* M) ?, M0 o9 z& V& V/ B //使用spring测试4 M; M: ^1 u! \ F! Z, g0 D
@RunWith(SpringJUnit4ClassRunner.class)
6 s3 K t1 ~3 D$ ` //加载spring配置文件5 J. E# ~3 m& G) }2 c; Q7 C& b8 a
@ContextConfiguration(locations = {* c' X6 M1 k! n( Z$ D- j2 f
"classpath:config/spring/applicationContext.xml",7 N; A0 T' r% _( A
"classpath:config/spring/applicationContext-dao.xml",) b4 Q* P8 }! o1 E
"classpath:config/spring/applicationContext-biz.xml",
7 w, ]8 C* @ F, S) }" M5 X "classpath:config/spring/applicationContext-web.xml" })
+ l4 y: D! J" N) F! l //自动注入8 q' B7 _) u: o4 d5 W
@Autowired! {" C+ T; l: z( Y% Q
private IUserDao iuserDao;
! T1 M7 u: Y W( `4 J+ x
; b- `: A! R$ H- J @Test/ z7 p4 B' Y" }7 p
public void saveUserTest(){& [) z9 S9 l- T1 _
//测试方法5 x( }" a% {2 N" D$ ]9 F
}
. z. |$ k- q$ ?9 ^ r8 `" p8 l10、完成业务层代码编写
, L' [) E. `, o& a2 b9 i) r11、完成表示层代码编写) _0 W& B) V* n0 x5 p0 H' R9 y
12、测试工程- }* e: f+ u7 Z. Z: k+ f0 j
) r" V5 K( ~' X" ]( |" A1 f/ z
13、spring处理hibernate延时加载
: T( b% X' }$ ]; ?) B: n* \$ Z 1、配置延时过滤器- T8 c" E, I m) \2 G4 L; W, { b
OpenSessionInViewFilter.class
% D8 T# k+ R" G) K7 O3 X 2、在web.xml配置OpenSessionInViewFilter/ j, O; D' j$ o6 ?3 @* }: Z
- ]; b) q6 | r3 V. X% f0 C! T/ {0 a
<filter>5 W6 f e8 g4 g1 p6 a$ l' ^* _% ^
<filter-name>openSessionInViewFilter</filter-name>, X6 W" X" ~4 x7 e: e
<filter-class>( Z3 U/ Q% p5 R7 [, U) [
org.springframework.orm.hibernate3.support.OpenSessionInViewFilter4 g5 K4 \5 o. Y% W; Y
</filter-class>
7 B! [% {) ?) R9 Z$ L <init-param>
8 g: v$ z$ t8 S N& l! O <param-name>sessionFactoryBeanName</param-name>7 f$ Y8 i# m2 V9 Y) \0 N2 u, {
<param-value>sessionFactory</param-value>/ r: N! J2 E h; A( I
</init-param>+ |! ^+ i1 K, ?2 i
</filter>
1 W! w1 u% e1 c <filter-mapping>4 D9 n+ @% g' F! q/ o1 d7 l, G
<filter-name>openSessionInViewFilter</filter-name> B: d6 @' R4 ~
<url-pattern>/*</url-pattern>
( E. a/ O; h) z6 ?- c. |0 r </filter-mapping>- p, U8 T" T( ^6 r' s5 X
! Y2 J9 I3 m: p$ N, D. {' R
|
|