该用户从未签到
|
1、创建Web Project
" h: }+ \0 n$ O2 U2、web工程与struts2整合
7 X' R# n1 v/ r" b$ X- ? (1)添加struts2类库+ `7 z/ F7 r Z- M9 l
struts2-core-2.1.8.1.jar
Z* a! n3 g* M8 [- O- ]# \% E5 } xwork-core-2.1.6.jar
" t! o% v0 F: A commons-fileupload-1.2.1.jar5 I+ E' k+ {6 Q5 b, W
commons-io-1.3.2.jar( p7 J7 o7 c# E1 i) U/ q. J
ognl-2.7.3.jar
6 d4 _5 c/ {9 C1 H2 e( { freemarker-2.3.15.jar
7 j8 h O# z( @1 g" m (2) 在web.xml文件中添加struts2集成
" I( O% j9 C. V0 [2 j <filter>
6 n& m0 U3 x+ D' c+ @9 p <filter-name>struts</filter-name>% |" }/ ]3 \5 G. \
<filter-class>% a1 R5 F1 m! m
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
6 w6 q. s D4 z* v9 ~ </filter-class>0 |6 g0 \7 g+ i
<init-param>7 u9 Y3 `5 P- b Z, l! l
<param-name>config</param-name>$ q0 O! U/ a$ v+ f5 k+ r
<!--
" y! I7 R$ q- O1 s, }, {' S; b) [ 修改struts2默认配置文件,
4 v2 X) t: G. I/ ]$ I+ K 必须把struts-default.xml,
& Z4 n8 Z# ]- T8 C0 Q! y( }* q struts-plugin.xml一起添加. |& P/ G1 g. H2 O' }- S, ~
必须:按顺序添加
+ \- r( G; O, y/ r& U S -->
" b- y$ D- `) ? b7 f8 T5 p4 y8 ^: I <param-value>
' {; P; Q7 J% b8 s struts-default.xml,struts-plugin.xml,config/struts/struts.xml
4 l8 M2 R3 A, i# A! M4 v$ d </param-value>
8 H1 E$ Q' e7 b </init-param>7 z h+ l/ E7 z$ j: ^) v: V9 ^
</filter>2 K4 I+ E/ O1 w8 N% i( d" b9 V
<filter-mapping>6 `2 b1 p* B* N$ b0 }
<filter-name>struts</filter-name>$ |: O* a2 h5 i
<url-pattern>/*</url-pattern>
l& A7 [! m6 P </filter-mapping> . H- Q; K4 ~7 `/ E3 M
<!--struts2 *.action struts2 *.do-->
/ t( x! J2 U4 A (3)创建struts2配置文件struts.xml配置 ; { ?+ f/ }- Y% K2 x6 I2 g) l+ r1 ?
(4)完成页面跳转
2 f" ?- f% p9 S, X3 Q4 E3 l3、测试struts2工程
' r$ @+ g, o: ?# _4、struts2与spring集成
' }) d- i7 I% y/ m1 F (1)添加spring类库与struts支持spring插件' z3 P! U/ _, Q" X* j2 |
struts2-spring-plugin-2.1.8.1.jar4 m# o# r* R# t: [; z5 H% h/ ^
cglib-nodep-2.1_3.jar2 C% J! d' s. s4 Q1 B' S* ~
commons-logging.jar
& A5 S4 g, j5 w+ J, ?5 u log4j-1.2.15.jar2 v' a' G: ?9 A! c; b
spring.jar7 S+ W5 ~; g6 w- ?" N6 k' v" {
dom4j-1.6.1.jar/ t) l/ O0 f. m- U5 r
(2)在web.xml中完成spring集成
9 M1 d$ L g. u- H6 a0 G6 q <listener>( J+ m3 O; s! N- H# Q1 L0 y
<listener-class>1 e& T! P" {0 L
org.springframework.web.context.ContextLoaderListener
7 A6 z6 z1 c' U! }8 a </listener-class>
: P4 |) R+ f7 i# d9 j </listener>0 @: N! m2 s# L9 ^) L2 Z
<context-param>
& X+ N" Z) h: j' e0 ~4 } R5 ? <param-name>contextConfigLocation</param-name>
' u. L0 u+ O( H <param-value>7 x! T/ [8 H8 m3 L% I2 d
classpath:config/spring/applicationContext.xml) i, l8 a" j9 {7 @- `" y
<!--classpath:config/spring/applicationContext*.xml-->: w0 Z5 P( k( M# ?& r
</param-value># I' f* m% B( z
</context-param>
4 ?0 p( A; I6 q) y3 U (3)创建spring配置文件applicationContext.xml3 P. j: x) B) E5 H. |
(4)在struts2配置文件中添加spring 集成常量9 x* Q- T" y. R1 c
<!-- 设置集成spring框架 -->2 n/ \/ r$ D, L1 n- E; a# b
<constant name="struts.objectFactory" value="spring"/>
8 f# e/ I8 W# \ (5)spring管理struts2中Action
# P# ]7 H0 g: o (1)在spring 配置文件中加入bean管理
7 p% J, e& ?+ o5 S <bean id="userAction" class="com.tarena.web.action.UserAction" >9 z8 K' L, z r
</bean>
& ^' H9 Z* u5 N8 q3 T2 C( y (2)修改struts-user.xml配置
3 C, B* U4 v9 T' s <action class="userAction" >; m5 F" @3 c, D, H6 [4 v7 ^: a
</action>/ e1 m& }# F+ f/ Z5 o
5 测试struts+spring集成
% K& y/ P# H, L5 I n, D- K8 e- Z6 spring+hibernate集成- i: j/ Z0 ^* u6 A/ x' `
(1)添加hibernate类库2 p; K% F9 R: `1 h9 u' o$ j4 Y- F
slf4j-nop-1.5.8.jar6 d1 r8 Z9 c, ~- b
slf4j-api-1.5.8.jar- W! s5 [( o6 d! [$ ^
jta-1.1.jar% Y: {( t6 ]1 u4 A6 _
javassist-3.9.0.GA.jar- f) G2 J: J$ y- u
hibernate3.jar
. ?. ^! ~& n1 X/ J" @: I commons-collections-3.1.jar6 G j' [/ s# d& V7 D5 G3 s
antlr-2.7.6.jar* L* Y3 h$ I' b9 `
(2)添加MySQL驱动类库
! v( H; K, y2 Q; P2 D. r% c mysql-connector-java-5.1.16-bin.jar- p+ i% {# W7 n# n0 @. O
(3)创建实体类- Y k! F- Q' w6 x3 ]5 V
(4)编写User.hbm.xml映射文件: k+ t; D7 P6 j8 w
(5)反向生成表结构$ E' M- p! r5 d
(6)spring管理hibernate
; u! y( X0 R2 ^: | 在spring applicationContext.xml配置文件中添加spring对hibernate管理( H% z; R; ~7 U! m4 x3 h. t
(A) 添加DBCP连接池# _9 [$ n* I. }6 R) D
a、添加类库
" ~! ^1 b+ {2 X' R2 i( Y commons-dbcp.jar, h) W+ Q t0 L; y3 g- R
commons-pool.jar
2 m" R/ `' o: P& Z8 H: p b、applicationContext.xml在配置连接池. H2 g0 ]2 }' z
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">: B9 n) ~3 d) p1 i W
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>- y* {* X2 N a4 Z
<property name="url" value="jdbc:mysql://127.0.0.1:3306/mydb"/>
0 l6 N& d9 i y0 E& V6 t1 P <property name="username" value="root"/>
7 R, H6 U" h$ Q E2 {+ V- x <property name="password" value="1234"/>
4 X6 c- z6 y. S) @4 z5 L <property name="initialSize" value="2"/>" f# U; J; p5 w: q6 s- y
<property name="maxActive" value="8"/>0 I8 X+ k9 P$ m$ r8 Q
<property name="maxIdle" value="5"/>
! ~' m0 M3 V. K5 m& O <property name="minIdle" value="3"/>0 U! }# p' E( o, v- p& w
<property name="maxWait" value="3000"/>1 u0 Q; F' E( x( ~% i
<property name="removeAbandonedTimeout" value="60000"/>
0 I& C" y' H7 z4 n <property name="removeAbandoned" value="true"/> V; H/ v9 j9 z/ L* n/ L% P
</bean>
8 e' c. c& C% G 连接池参数如下:
+ |' M# U6 w" N$ d- _: H1 F, t initialSize
3 b& X2 Y2 z2 {3 i- p 连接池启动时创建的初始化连接数量
8 V' k: N# W- v, o9 j% ] (默认值initialSize :连接池启动时
t: X5 t6 Z7 f. A: q) m' }1 H 创建的初始化连接数量(默认值为0)
: p9 r/ r! ?, ?& S+ K& t- e maxActive ; S8 R1 @! L8 m
连接池中可同时连接的最大的连接数
% ^. i! F+ n" ?% e. w (默认值为8 ,调整为20,高峰单机器在20并发左右,
7 Q9 Z# x5 s4 B; j* Y- P7 r 自己根据应用场景定)
# f+ x0 S6 b8 F% A1 `2 t2 O maxIdle- ^& ^/ @* B# s
连接池中最大的空闲的连接数,
g* X0 C( B: Y, z) U* O 超过的空闲连接将被释放,
) U# y. T' ~1 J" b; | 如果设置为负数表示 不限制(默认为8个)- v4 P- }5 @. S1 a# Q
minIdle
1 ]) U* O: X f- Q 连接池 中最小的空闲的连接数,低于这个数量会被* I. N& H/ i0 Y7 S" J
创建新的连接(默认为0,调整为5, 该参数越接近
9 [/ H: u0 @3 W' U3 h" k% F maxIdle,性能越好,因为连接的创建和销毁,
5 l1 {+ }. W3 d& j) x 都是需要消耗资源的,但是不能太大,
! b: W' r' k, \ U6 W8 B! O+ d! Q1 s 因为在机器很空闲的时候,也会创建低于
6 B8 V5 {4 _9 N) e minidle个数的连接) * ?4 A4 n0 e6 l
maxWait
+ e5 h5 o3 Q$ @' {/ e, }! A# k u( s6 m 最大等待时间,当没有可用 连接时,+ w# |) P+ p) K N
连接池等待连接释放的最大时间,
0 t7 L9 ^" _+ v2 z! d. O 超过该时间限制会抛出异常,+ H6 E+ U( r7 r8 L, P" u$ @
如果设 置-1表示无限等待(
! X5 b6 M- G) N6 b1 t 默认为无限,调整为60000ms,
) G( \8 s" L& ? F4 `; A 避免因线程池不够用,而导致 请求被无限制挂起) $ v- q- R: I7 ~; |- k
removeAbandonedTimeout :$ _. t2 K7 W7 m/ Z3 [
超过时间限制,回收没有用(废弃)的连接 1 U" H, r, a% s0 R$ ~0 y
(默认为 300秒,调整为180)
! z; v8 H3 r% d0 i9 w removeAbandoned :, h4 Y/ L0 I, ]1 D0 |
超过 removeAbandonedTimeout时间后,+ `& {+ K. L+ y0 W3 l
是否进行没用连接(废弃)的回收" D, u" Q. Y; a7 K0 v/ b+ T
(默认为 false,调整为true)
+ T, x9 C' Q9 K6 _/ j0 ^4 x7 }# d (B)spring管理hibernate实体映射文件:
% y# j( k! w) e R5 b0 J <bean id="sessionFactory"
/ i8 P# ?& E; N! g, g class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">, b3 z$ \# ^9 d' I8 x! s k) L
<property name="dataSource" ref="dataSource" />* T/ E' t/ {. t# b
<property name="hibernateProperties">" w3 O* y6 c# a3 S" y
<props>1 q2 B3 p8 r+ B+ e& e, R, d
<prop key="hibernate.dialect">
2 C* c5 V. u4 D% B org.hibernate.dialect.MySQLDialect u c# G. S6 e) c+ \7 E- q$ \" I8 J5 u
</prop>
- C9 O/ J9 j9 f P4 T <prop key="hibernate.show_sql">true</prop># w( H$ c' L4 f: `
<prop key="hibernate.format_sql">true</prop>
: L+ s7 x- ?1 |6 B9 n4 m) f! c </props>
) q" F- s! f0 F0 o4 R2 _! K1 a0 K I </property>
) [5 L0 r3 q0 } <property name="mappingLocations">+ z" j8 S% o: ]9 C/ r, w
<list>% \4 F; S( N% A1 V0 a
<value>! n* @' m3 e2 }6 ?
classpath:config/hibernate/hbm/User.hbm.xml
9 s" M7 `4 u0 e l6 S. f& L </value>4 ^8 x+ I5 b" Z, b
</list>- x1 s3 E; e. R; M/ K) a! f* N0 s
</property>+ A+ k+ x3 {; _2 m; }2 v- v
</bean>7 T# Z s& H( a3 q9 F1 n0 \
(C)spring读写属性(properties)文件
$ D) j% l! A0 j6 I7 a* u a、创建属性文件 db.properties' P" b7 }( u! B8 H# z' X& D
b、在applicationContext.xml配置
& A# ^( x# z# N. L/ i$ q1 G4 k <bean id="propertyPlaceholderConfigurer"
% m8 N% ~( F/ f$ j, T class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">* E! T; }% j: ^% A. `4 }* W
<property name="locations">. o4 `2 ?& I8 G, E
<list>8 M3 l, _6 Q. @" _( U% u' h
<value>classpath:config/props/db.properties</value>* {3 `) H: e7 o" u& _6 X1 X' F
</list>/ `. C0 J* t) K! B+ g
</property>; l0 a1 Q8 N( m. Y/ g
</bean>6 i0 [0 t* U8 ]& a. h# a& @7 w
c:引用: ${username}
' i7 o. z. L/ L7 p7 E4 b9 t9 f
1 U2 U% ]$ {4 Z, O y (8)spring分文件管理
2 s9 G% S& Z# a3 t% U4 ^ <!-- 引入其他spring 配置文件 -->; o$ c) w4 K$ F l; h" p- r; T
applicationContext.xml引入下列文件
- u: Y" A, T! Z4 ^8 V5 l; D <import resource="applicationContext-web.xml"/>
4 i6 H- Z7 c2 e2 ? <import resource="applicationContext-biz.xml"/>
" z6 S: t* E7 Q) K <import resource="applicationContext-dao.xml"/>
) `3 C0 x: I/ @+ k7、开发数据访问层/ G$ U$ |, ^+ X) ~4 w. h$ C
使用spring提供hibernate 模板类 HibernateDaoSupport
0 h& S' l" b$ D% @( \% r UserDaoImpl extends HibernateDaoSupport w+ ?: y& }* e2 ~) W
在UserDaoImpl注入到spring 配置文件 applicationContext-dao.xml
) O$ I" p3 N& A5 ]* s% U <bean id="userDaoImpl" class="com.tarena.dao.impl.UserDaoImpl"># J% p3 v, ^) z/ s X B8 \' b; u0 u+ g6 n
<!--HibernateDaoSupport中的sessionFactory-->/ |" l: \) Y( v' v2 O$ R' t
<property name="sessionFactory" ref="sessionFactory" />
4 k9 H( r5 R* _8 | </bean>
4 E0 }. }; K, n8、添加spring声明事务管理(AOP)
* h( x& H' z O 声明式事务管理:
k; D! B8 e8 x! T/ n5 w" I p 添加spring 类库3 d& I0 t5 i Z- u4 H: K
aspectjrt.jar
, u! T" |. Y7 S6 u aspectjweaver.jar
& c: F9 F$ e7 Y$ m 了解事务的几种传播特性( b$ p+ k0 t1 }- T/ F3 j
: `* Z: F; G/ c3 E2 E (1)PROPAGATION_REQUIRED:
( a Y/ L! ?6 Y1 h 如果存在一个事务,则支持当前事务,如果没有事务则开启。
1 ^# h q) T( H" ]8 \ (2)PROPAGATION_SUPPORTS: + W+ F. ~9 r/ }+ G7 p8 U
如果存在一个事务,支持当前事务。
5 u9 d" W. F' q. V: v 如果没有事务,则非事务的执行。0 @! q2 `! h( m/ ]
(3)PROPAGATION_MANDATORY: - |) P0 Y& Y) @2 g1 I( ?/ I
如果已经存在一个事务,支持当前事务。+ v5 t! I$ S4 ^) F' _
如果没有一个活动的事务,则抛出异常。$ b# `) `0 m* x% ^6 j0 {
(4)PROPAGATION_REQUIRES_NEW: ( _% \1 |+ o# v8 T* C* |4 d. o
总是开启一个新的事务。如果一个事务已经存在,, K2 `5 K T4 L0 i# `
则将这个存在的事务挂起。; a5 l# r9 h5 W
(7)PROPAGATION_NESTED:(spring特有)& t3 [" Y I5 E# {
如果一个活动的事务存在,则运行在一个嵌套的事务中.
% ^. n7 t7 V2 z; u$ p3 k3 } 如果没有活动事务, 则按TransactionDefinition., U" m W* ~; h" \
PROPAGATION_REQUIRED 属性执行* }5 [1 }# k: }: j, }, F8 S5 r
$ x1 u0 D5 V( w; X& }- L6 s (5)PROPAGATION_NOT_SUPPORTED: . v! ]) I, ^$ ?& u4 X. c& P( @1 F: }
总是非事务地执行,并挂起任何存在的事务。: V: ]0 c; [3 [5 A% X+ e! N4 Q
(6)PROPAGATION_NEVER:
2 i5 e3 A& Y! f3 ~0 O# I 总是非事务地执行,如果存在一个活动事务,则抛出异常。* T9 j0 W' L0 w- c9 j2 V7 T
9 A7 @: I/ f, U+ v
% i. ?/ o2 M) D' d
<!-- 配置声明事务管理 spring2.x-->: {" @, Z# z' E3 A, g/ Q: w/ `! P
<!-- 定义事务管理 -->7 I: R) J1 Z2 b+ f
<bean id="transactionManager"! {+ J+ P! l" r/ l4 g, z% {0 k
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
; h' X; a/ {; w6 K" ~ <property name="sessionFactory" ref="sessionFactory" />
+ p$ f/ k# H: h8 I </bean>
3 B' B0 O. c* x `; e <!-- 事务规则 -->
, y. a7 c" s0 h$ d9 ?8 Y9 V8 i <tx:advice id="tmAdvice" transaction-manager="transactionManager">
% Q% L0 C1 G. g0 H$ n4 c <tx:attributes>( w# ^% u* F% v5 ~5 Z' a
<!--*通配符 save* 方法名必须是以save开始-->2 Y' ~2 x9 X* w2 q9 g
<tx:method name="save*" propagation="REQUIRED" />8 q( k# A* D0 Q
<tx:method name="update*" propagation="REQUIRED" />5 C$ C4 G$ A1 o3 h5 P
<tx:method name="delete*" propagation="REQUIRED" />
* F/ v3 v* w% r- X! Z0 a <tx:method name="find*" read-only="true" />
$ r0 y$ D1 l* s+ t, O <!-- read-only 只读:-->/ X" n6 a* D) m- i2 m& _6 `
</tx:attributes>
2 H- J3 F, ^% G </tx:advice>
: S% g* {0 \+ ], q <aop:config>
8 f" l! i" w* U4 B% @ <!-- point cut -->
8 N& @5 h2 P1 j* Y+ B l( A <aop:pointcut id="pointCut": ]; j$ @' q. }1 H6 `) \
expression="execution(* com.tarena.biz.*.*(..))" />5 f* z$ t( r- o, O- n, x8 x, L' M
<aop:advisor advice-ref="tmAdvice" pointcut-ref="pointCut"/> " ^7 W2 w/ k% _! _8 Y7 h" X7 C
</aop:config>
- W: ?9 l, ?4 G9 v* R C5 z2 u/ W / F* o5 j; q4 p7 g
9、测试
3 y% V) E% t$ Z# k 添加测试类库 spring2.5.6
6 t$ C o% U4 C, d& u6 k7 P0 T junit-4.4.jar; [* Z7 H3 f( s' k4 M
spring-test.jar
. {% E$ T: `/ d3 G4 d! L9 v //使用spring测试
5 x; \0 N! ^% c" j( B' R @RunWith(SpringJUnit4ClassRunner.class)
- ~9 S" G3 S! h( y' t$ D) M$ W //加载spring配置文件
( S' e7 \5 [0 ?5 z& l @ContextConfiguration(locations = {
! B6 V% |$ [: ]4 @" j; C "classpath:config/spring/applicationContext.xml",
! q* b5 ]5 G, T2 v D "classpath:config/spring/applicationContext-dao.xml",0 \) Z0 F* ^2 z1 t8 L
"classpath:config/spring/applicationContext-biz.xml",. S+ e- j6 P" Q( N8 W
"classpath:config/spring/applicationContext-web.xml" })
. \0 z; B) p, E //自动注入
+ j; x3 M: F8 M/ y0 L @Autowired
( _% d2 V& r K. O9 d% E+ Y private IUserDao iuserDao;' @/ q/ B5 ^* R" R( k
" [$ K( L f9 d0 x! u8 A" w
@Test
1 f6 h1 ^4 c2 N1 v+ n4 }7 e0 V9 u public void saveUserTest(){
! F0 j" D# n8 @- j4 C //测试方法
3 B. O6 e j1 Z- J5 }7 M" B W }
0 @6 y" G' T) h8 q: u+ \10、完成业务层代码编写
/ ~* V' h8 H/ m" M9 t11、完成表示层代码编写
" |4 Q% Q+ i1 \4 x+ b) |* O12、测试工程
" w) `; L& C0 i8 O7 G/ ~* l; H2 T1 u. J9 ]3 U+ c( _' [
13、spring处理hibernate延时加载
; H* e" b% r' Y3 b$ R. { 1、配置延时过滤器: O! S! n) m3 H j/ C7 G l8 G
OpenSessionInViewFilter.class
6 W; X3 A2 [* o' U$ m+ D; y9 `8 @ 2、在web.xml配置OpenSessionInViewFilter
s1 g& |$ j- G& v 1 `7 m8 \, s% \3 n
<filter>
& L/ H; D* C% K <filter-name>openSessionInViewFilter</filter-name>
4 T2 |# V b# x# O* T% [ <filter-class>
?4 j" j$ Q' C# f8 x$ A org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
* X' Z/ e+ a, d7 X9 G </filter-class>) a* Q; Y$ J Y5 M& C0 c" l
<init-param>
7 N" N" Z/ ~& w4 x* ^$ c( B <param-name>sessionFactoryBeanName</param-name> F5 |# f6 K f# |9 u) m$ E* s5 I
<param-value>sessionFactory</param-value>
5 K. N- B" ]2 y/ t! s$ s </init-param>" W2 b4 E: r0 C6 A% @/ Z% ?
</filter>6 Q- ~" A0 f0 A( F5 j
<filter-mapping>
3 m, N1 c! o8 W# B0 L <filter-name>openSessionInViewFilter</filter-name>
1 n/ }2 Y$ C i <url-pattern>/*</url-pattern>
* l; X& w: ~- D/ q# s9 G3 K8 } </filter-mapping>1 b% C Q( @. @2 t! E) ]
" U) m+ l* O" C% Q! M- O2 @7 Z9 c8 Y
|
|