Singleton的问题!!help!!

scorptio 07-12-08
              

最近在做一些代码安全性检查,使用了Fortify。发现了一些曾经引以为豪的代码既然会出现高危的错误。希望各位达人给予帮助。
设计初衷:共享WebApplicationContext,通过getBean(String beanName)取得对应的bean处理相应的业务逻辑。 public class BaseAction extends Action {
private WebApplicationContext wac;
protected ServletContext context;
public void setServlet(ActionServlet actionServlet) {
super.setServlet(actionServlet);
context = actionServlet.getServletContext();
wac = WebApplicationContextUtils.getRequiredWebApplicationContext(context);
}

protected Object getBean(String beanName) {
return wac.getBean(beanName);
}
} 高危错误代码: context = actionServlet.getServletContext();
wac = WebApplicationContextUtils.getRequiredWebApplicationContext(context);
错误原因分析:BaseAction继承自Action,单例实现。该类含有属性:wac与context,在多线程环境下不能保证这两个属性的合理逻辑。于是掉入了一个单例模式的陷阱。(请各位达人完善)
解决方法:等待中...(请各位达人帮助)

              

power1128
2007-12-08 15:52

如果是Struts1的话,它的Action的确是单态模式,也就是对n多request(请求的Action相同)只会用一个Action对象来响应,所以Action里不应该定义实例变量.
Struts2(或者说是Webwork)就不是单态模式,你那样做就没有问题

你这个工具挺有意思,很好,很强大.改天下来看看

[该贴被power1128于2007-12-08 15:54修改过]

scorptio
2007-12-08 17:40

请大家多多帮助!
由于检测出高危错误,以至项目无法提交客户.
希望各位给出最佳的解决方案.目前的解决方法是将wac与context设置为static变量,虽然不会再有高危的错误报告,可是总是感觉不大对劲..
1.系统中各模块的Action都继承于BaseAction.setServlet方法会在每次加载各模块Action子类的时候调用,定义成static会不会有什么问题??
2.单例中不应该出现有状态的局部变量\有状态的全局变量\无状态的局部变量.而只能出现无状态的全局变量,这句话是否正确?

banq
2007-12-10 10:08

写的方法是高危,但是看你的方法内容,则没有关系。

你的方法内容是获得一个Web项目的一个单例,实际就是SPring容器,而且大部分是读,而不是读写并加。

单例陷阱我已经在以前帖子中说了,只有在单例+写+同步等操作下才可能死锁,因为代码不可控性,今天你注意没这么做,不代表其他无知的人不这么做,所以,这种singlton会被严谨的工具认为是高危,这是正确的。

scorptio
2007-12-10 21:15

谢谢 banq!
如果需要消除这段高危代码,需要如何重构.
因为只是存在读操作,我是否可以把wac与context定义为static(这样工具不会报错)

请问这样改会不会有问题?

2Go 1 2 下一页