您的位置:首页 > 编程语言 > Java开发

再说spring下action的作用域

2009-12-12 21:52 351 查看
在作版块管理action的时候,一直忘记写@Scope注解,测试的时候有很多问题,当然,这些问题应该都是和hibernate有关的,只是在测试的时候,发现BoardAction没有加@Scope注解,再想到原先出现的问题,进一步理解为什么在默认的作用域下(singleton),不能接受第二次输入的值.

在原来写注册用户的action时,当使用默认的作用域,第二次提交时setUser并不会被执行,那应该是因为,前一次的校验信息存在,使得struts不去运行setUser.在这次的BoardAction中,同样使用默认的作用域,setBoard是会被执行的.

从线程安全的角度来考虑,如果使用默认的作用域,则action是单例,则有可能出现线程不安全,第一次运行action可能会用到第二次的值(private 成员变量,从form传来的值),因此应当使用@Scope注解,用prototype模式.或者使用request,session模式,使用后两种模式,需要在web.xml中配置listener或filter.

发现BoardAction没加注解是因为做下面这个测试:
不知道为什么在BoardServiceBean.update()时,总是会有一句delete from Board_user_table where Board_id=?语句.会产生这样一条语句的原因是:在更新board的时候,board的manager是空的,但我设计的目的只是想部份更新,并不想更新manager.
但是,当在find()方法中使用System.out.println(board.getSubs().size());后(实际运行),就不会有delete语句了.
即使换一个board id也是如此,由于测试数据不完整,大部份board都没有manager,可以这样理解,当执行了find()方法后,board中的manager就被赋值了,此后,程序并没有改变过manager的值,所以,就不必去更新,也应没有delete语句了.第二次提交请求,BoardAction中的board是仍然是原来那个board(用struts的debug标签跟踪,发现是相同的),所以之后就也没有delete语句了.

当然,指定了@Scope("prototype")后,上述方法就无效了,因为每次请求都产生一个新的action,相应的成员变量board也是一个新值,所以都会产生一条delete语句.

同时,spring事务管理下的Hibernate.initialize(board);无效,必须显性的用board.getSubs().size()等类似方法.

这几天也就一直在研究懒加载和多出这一条delete的问题.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: