- 浏览: 607659 次
- 性别:
- 来自: 北京
-
最新评论
-
黑色幽默_cool:
这种不负责任的文章,多看一分钟都是浪费。
为什么使用ibatis而不用spring jdbcTemplate -
leibinhui:
不错啊 非常实用
JS正则表达式详解[收藏] -
suu:
写个存储过程,爆如下错误,是不是游标里的数据太多引起的?无法执 ...
使用Spring jdbc template调用Sybase带有返回结果集的储存过程-要点 -
travellers:
有SVR6了,为什么很多还在使用SVR4呢?
什么是SVR4?我们为什么要选择SVR4? -
dotjar:
生活是多么美好阿!
老公日记
这是一个真实的案例,我们在项目中使用Spring和ACEGI,我之所以选择ACEGI,除了它对权限的良好控制外,
我还看好它的SecurityContextHolder,通过代码
我可以很容易在系统任意一层得到用户的信息,而不用把用户信息在参数里传来传去,(这也是struts的缺点之一)
但是我在每一次要得到用户信息的时候都写上面的一段代码,未免有些麻烦,所以我在BaseService, BaseDao里都提供了如下方法:
这样在其他的Service和Dao类里可以通过
来得到用户的信息,这也为问题的产生提供了温床。请看如下代码:
这段代码在单元测试的时候不会用任何问题,但是在多用户测试的情况下,你会发现任何调用SomeService里someMethod()方法
的userID和userName都是同一个人,也就是第一个登陆的人的信息。Why?
其根本原因是Spring的Bean在默认情况下是Singleton的,Bean SomeServece的实例只会生成一份,也就是所SomeServece实例的user
对象只会被初始化一次,就是第一次登陆人的信息,以后不会变了。所以BaseService想为开发提供方便,却给开发带来了风险
正确的用法应该是这样的
小心的问一下 :
像本贴作者 最后说的
正确的用法应该是这样的
public class SomeServece extends BaseService implements SomeInterFace
{
public someMethod()
{
int userID = super.getUserInfo().getUserID();
String userName = super.getUserInfo().getUserName();
//bla bla do something user userID and userNaem
}
}
这样不是 重新获取么?
满足上面的三个条件,你有什么高招?你无法要求组内所有的人都很清楚Spring
不知道 java 里面有一种叫 Util 的方法?
写成Util方法,跟放在Base里有什么两样?如果提供了Util方法,写继承类的老哥一样回怎么写
问题不是还是存在?
不放入成员变量就行了啊,别人都说了无数次了.
不知行否.
这个是正解,一定不能这么用
满足上面的三个条件,你有什么高招?你无法要求组内所有的人都很清楚Spring
不知道 java 里面有一种叫 Util 的方法?
写成Util方法,跟放在Base里有什么两样?如果提供了Util方法,写继承类的老哥一样回怎么写
问题不是还是存在?
不放入成员变量就行了啊,别人都说了无数次了.
不知行否.
这个我从一开始就知道!
那段错误的程序不是我写出来的,
是我贴出来讨论的
气死我了!
这位仁兄貌似没有明白我在说什么?
人都需要一个成长的过程的,不能把人一棒子打死,不能期待项目组里的都是老鸟,怎么都会有些小鸟的,小鸟只要勤奋认学,总会成为老鸟的!
满足上面的三个条件,你有什么高招?你无法要求组内所有的人都很清楚Spring
不知道 java 里面有一种叫 Util 的方法?
写成Util方法,跟放在Base里有什么两样?如果提供了Util方法,写继承类的老哥一样回怎么写
问题不是还是存在?
满足上面的三个条件,你有什么高招?你无法要求组内所有的人都很清楚Spring
不知道 java 里面有一种叫 Util 的方法?
我还看好它的SecurityContextHolder,通过代码
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
我可以很容易在系统任意一层得到用户的信息,而不用把用户信息在参数里传来传去,(这也是struts的缺点之一)
但是我在每一次要得到用户信息的时候都写上面的一段代码,未免有些麻烦,所以我在BaseService, BaseDao里都提供了如下方法:
/** * get current login user info * @return UserInfo */ protected UserInfo getUserInfo() { return getUserContext().getUserInfo(); } /** * get current login user context * @return UserContext */ protected UserContext getUserContext() { Authentication auth = SecurityContextHolder.getContext().getAuthentication(); return (UserContext) auth.getPrincipal(); }
这样在其他的Service和Dao类里可以通过
super.getUserContext(), super.getUserInfo()
来得到用户的信息,这也为问题的产生提供了温床。请看如下代码:
public class SomeServece extends BaseService implements SomeInterFace { private UserInfo user = super.getUserInfo(); public someMethod() { int userID = this.user.getUserID(); String userName = this.user.getUserName(); //bla bla do something user userID and userNaem } }
这段代码在单元测试的时候不会用任何问题,但是在多用户测试的情况下,你会发现任何调用SomeService里someMethod()方法
的userID和userName都是同一个人,也就是第一个登陆的人的信息。Why?
其根本原因是Spring的Bean在默认情况下是Singleton的,Bean SomeServece的实例只会生成一份,也就是所SomeServece实例的user
对象只会被初始化一次,就是第一次登陆人的信息,以后不会变了。所以BaseService想为开发提供方便,却给开发带来了风险
正确的用法应该是这样的
public class SomeServece extends BaseService implements SomeInterFace { public someMethod() { int userID = super.getUserInfo().getUserID(); String userName = super.getUserInfo().getUserName(); //bla bla do something user userID and userNaem } }
评论
41 楼
IvanLi
2007-02-01
这是正确的用法
40 楼
JavaFlasher
2007-01-30
小心的问一下 :
引用
Acegi SecurityContextHolder 默认采用 ThreadLocal 存储 authentication 对象, 每次使用当然都要重新获取,
像本贴作者 最后说的
引用
正确的用法应该是这样的
public class SomeServece extends BaseService implements SomeInterFace
{
public someMethod()
{
int userID = super.getUserInfo().getUserID();
String userName = super.getUserInfo().getUserName();
//bla bla do something user userID and userNaem
}
}
这样不是 重新获取么?
39 楼
jianfeng008cn
2006-12-28
很有意思的一个帖子嘛 尤其是“老哥改行”这一说 !
38 楼
差沙
2006-12-27
不好意思,不知道怎么删除自己的帖子。。刚才的回复是废话
37 楼
差沙
2006-12-27
再次无语。。。。。
Service既然是单例了,为什么还要写属性在里面?单例的东西不能写任何表示状态的东西。。。。
直接这样就可以了
Service既然是单例了,为什么还要写属性在里面?单例的东西不能写任何表示状态的东西。。。。
直接这样就可以了
public class SomeServece extends BaseService implements SomeInterFace { public someMethod() { int userID = getUserInfo().getUserID(); String userName = getUserInfo().getUserName(); //bla bla do something user userID and userNaem } }
36 楼
shaucle
2006-12-25
友谊第一,呵呵
35 楼
IvanLi
2006-12-25
ahuaxuan 写道
不好意思啊,让写代码的人来看看这篇文章吧,其实我们都是对事不对人的,我个人的想法是让中国软件的水平成为世界一流,需要大家努力,大家不应该程序员相轻,楼主见量啊,努力努力,呵呵

34 楼
IvanLi
2006-12-25
shaucle 写道
Ivan Li 写道
Feiing 写道
Ivan Li 写道
满足上面的三个条件,你有什么高招?你无法要求组内所有的人都很清楚Spring
不知道 java 里面有一种叫 Util 的方法?
写成Util方法,跟放在Base里有什么两样?如果提供了Util方法,写继承类的老哥一样回怎么写
public class SomeServece extends BaseService implements SomeInterFace { private public someMethod() { int userID = this.user.getUserID(); String userName = this.user.getUserName(); //bla bla do something user userID and userNaem } }
问题不是还是存在?
public someMethod() { UserInfo user = someUtil.getUserInfo(); int userID = this.user.getUserID(); String userName = this.user.getUserName(); //bla bla do something user userID and userNaem }
不放入成员变量就行了啊,别人都说了无数次了.
不知行否.
这个是正解,一定不能这么用
33 楼
shaucle
2006-12-25
晕死,按了个ctrl+x
32 楼
shaucle
2006-12-25
Ivan Li 写道
Feiing 写道
Ivan Li 写道
满足上面的三个条件,你有什么高招?你无法要求组内所有的人都很清楚Spring
不知道 java 里面有一种叫 Util 的方法?
写成Util方法,跟放在Base里有什么两样?如果提供了Util方法,写继承类的老哥一样回怎么写
public class SomeServece extends BaseService implements SomeInterFace { private public someMethod() { int userID = this.user.getUserID(); String userName = this.user.getUserName(); //bla bla do something user userID and userNaem } }
问题不是还是存在?
public someMethod() { UserInfo user = someUtil.getUserInfo(); int userID = this.user.getUserID(); String userName = this.user.getUserName(); //bla bla do something user userID and userNaem }
不放入成员变量就行了啊,别人都说了无数次了.
不知行否.
31 楼
ahuaxuan
2006-12-25
不好意思啊,让写代码的人来看看这篇文章吧,其实我们都是对事不对人的,我个人的想法是让中国软件的水平成为世界一流,需要大家努力,大家不应该程序员相轻,楼主见量啊,努力努力,呵呵
30 楼
IvanLi
2006-12-25
ahuaxuan 写道
feiing正确,楼主没有明白我的话,呵呵,可能我说得不够明白,全局变量会在实例初始化的时候赋值,private UserInfo user = super.getUserInfo(); 这样写,这个user变量只会被一次赋值(产生这个service对象的时候),不会再变了,并且,user是代表状态的,不能够作为service(singleton)的全局变量的,这在哪里都有说明的呀,所以不是我不明白你在说什么,是你不明白我在说什么,我说
我明白你的意思,你就是找出了个原因,真正的有一个原则性的东西你违反了,现在应该明白点了吧
引用
你又把user设置为它的全局变量,而且还这样写:private UserInfo user = super.getUserInfo(); ,大错特错,
,这还不够清楚吗。 一是只会被赋值一次,二是如果多线程修改user会造成数据紊乱(虽然你这里没有修改,但是你这样用会误导组里其他不知道得成员,使他们认为这样用是没有问题得),单例的service里不能放有状态的,这是原则,难道我说得真得不够明白吗???
我明白你的意思,你就是找出了个原因,真正的有一个原则性的东西你违反了,现在应该明白点了吧
这个我从一开始就知道!


那段错误的程序不是我写出来的,






29 楼
ahuaxuan
2006-12-25
feiing正确,楼主没有明白我的话,呵呵,可能我说得不够明白,全局变量会在实例初始化的时候赋值,private UserInfo user = super.getUserInfo(); 这样写,这个user变量只会被一次赋值(产生这个service对象的时候),不会再变了,并且,user是代表状态的,不能够作为service(singleton)的全局变量的,这在哪里都有说明的呀,所以不是我不明白你在说什么,是你不明白我在说什么,我说
我明白你的意思,你就是找出了个原因,真正的有一个原则性的东西你违反了,现在应该明白点了吧
引用
你又把user设置为它的全局变量,而且还这样写:private UserInfo user = super.getUserInfo(); ,大错特错,
,这还不够清楚吗。 一是只会被赋值一次,二是如果多线程修改user会造成数据紊乱(虽然你这里没有修改,但是你这样用会误导组里其他不知道得成员,使他们认为这样用是没有问题得),单例的service里不能放有状态的,这是原则,难道我说得真得不够明白吗???
我明白你的意思,你就是找出了个原因,真正的有一个原则性的东西你违反了,现在应该明白点了吧
28 楼
IvanLi
2006-12-25
ahuaxuan 写道
象楼主这样写肯定出错呀,大家都用一个service对象,你又把user设置为它的全局变量,而且还这样写:private UserInfo user = super.getUserInfo(); ,大错特错,第一,spring管理的单列模式的bean中的全局变量应该是无状态的(这一点无论哪个文档上都有写吧,看来楼主对spring不是很熟,user明显是有状态的怎么能用作全局变量呢,肯定要把super.getUserInfo()放在service具体的方法里),第二看到楼上很多人不知道在说什么,不知所芸,有人说“可以修改配置文件,修改参数吧!!”,还有人说“改改配置,写个全局变量,什么问题也就解决了,哪有这么麻烦”,还有人说用ThreadLocal,acegi这种得到用户的方式本来就是ThreadLocal,还需要再用一个ThreadLocal吗??其实关键不在ThreadLocal这个地方。上面有个兄弟说得其实很清楚明白,只是我看大家都没有理解,flyspider说道:
这才是正确的,只不过大家都没有明天他在说什么
引用
Spring建议以singleton方式注入的依赖尽量是stateless的
这才是正确的,只不过大家都没有明天他在说什么
这位仁兄貌似没有明白我在说什么?
27 楼
IvanLi
2006-12-25
Feiing 写道
这种老哥, 还是去做别的行业吧
人都需要一个成长的过程的,不能把人一棒子打死,不能期待项目组里的都是老鸟,怎么都会有些小鸟的,小鸟只要勤奋认学,总会成为老鸟的!
26 楼
IvanLi
2006-12-25
这篇帖子的主要目的也是在说明四楼的哥们说的事情
只不过这个在项目中真实的出现了,所以发贴记下来
flyspider 写道
Spring建议以singleton方式注入的依赖尽量是stateless的
只不过这个在项目中真实的出现了,所以发贴记下来
25 楼
Feiing
2006-12-25
这种老哥, 还是去做别的行业吧
24 楼
IvanLi
2006-12-25
Feiing 写道
Ivan Li 写道
满足上面的三个条件,你有什么高招?你无法要求组内所有的人都很清楚Spring
不知道 java 里面有一种叫 Util 的方法?
写成Util方法,跟放在Base里有什么两样?如果提供了Util方法,写继承类的老哥一样回怎么写
public class SomeServece extends BaseService implements SomeInterFace { private UserInfo user = someUtil.getUserInfo(); public someMethod() { int userID = this.user.getUserID(); String userName = this.user.getUserName(); //bla bla do something user userID and userNaem } }
问题不是还是存在?
23 楼
Feiing
2006-12-25
Ivan Li 写道
满足上面的三个条件,你有什么高招?你无法要求组内所有的人都很清楚Spring
不知道 java 里面有一种叫 Util 的方法?
22 楼
shaucle
2006-12-25
不清楚自然会用得不好
就像俺们组里的成员用exception一样,到处乱用,乱catch
后来的办法就是专门开个会,统一讨论一下,再定制标准
就像俺们组里的成员用exception一样,到处乱用,乱catch
后来的办法就是专门开个会,统一讨论一下,再定制标准
发表评论
-
use hibernate3-maven to export sql based on entity
2011-08-07 18:19 1424<plugin> <group ... -
uninstall mysql completely in my Mac X 10.6
2011-08-07 12:19 1263sudo rm /usr/local/mysql ... -
my vimrc
2011-05-14 11:02 1750copy from http://www.vi-improve ... -
使用HSQLDB来作EJB3 EntityBean到Unit Test要点
2010-01-20 17:17 2147add <property name=" ... -
user xrandr to change my desktop's resolution
2009-12-16 17:04 1708xrandr --newmode "1280x ... -
XSS的关键之列表
2009-10-11 17:20 1862//this field are used tp esc ... -
python查看方法帮助(from dive into python)
2009-09-30 11:31 2661def info(object, spanding=10, c ... -
selenium 测试ajax的关键
2009-01-20 18:26 42681: waitForCondition(contidtion, ... -
RichFaces 手记
2008-10-07 15:46 0安装,除了richfaces 下载包中的jar( " ... -
代码检查工具
2008-09-25 11:48 2591findBugs, PMD, CheckStyle find ... -
CI工具hudson
2008-09-24 17:04 3144CI工具除了hudson,还有很多,例如CruiseContr ... -
创建solaris package step by step
2008-09-24 11:27 1948原文地址:http://www.ibiblio.org/pub ... -
什么是SVR4?我们为什么要选择SVR4?
2008-09-23 14:13 5010http://www.lslnet.com/linux/f/d ... -
IPS 中的pkg command学习笔记
2008-09-22 17:18 1864pkg(1): 使用pkg(1)来创建一个镜像,安装,升级,管 ... -
On Board前的学习计划
2008-09-18 09:37 15491:在virtual box 上虚拟一个OpenSolaris ... -
YUI Grid CSS的优雅设计
2008-09-02 22:38 2854最近加入了一个GAE的项目cpedialog,该项目的前端布局 ... -
我很懒,但是懒人有懒办法
2008-08-18 17:06 1836今天要使用jackrabbit做个小东西,上apache一看, ... -
当XPath遇上NameSpace
2008-07-23 19:39 6583在jdk5.0中,已经包含了对Xpath的支持,可一通过下面的 ... -
ubuntu下安装ipmsg-飞鸽传书
2008-07-21 09:32 29051 先下载 源码 下载的是gnome2版本的源码 http ... -
sudo 执行时无密码(不安全)
2008-07-17 17:18 2234sudo visudo root ALL=(ALL) ...
相关推荐
2. **Bean 容器**:Spring 提供了两种类型的 Bean 容器,即 Singleton Bean 容器和 Prototype Bean 容器。Singleton 容器管理单例对象,而 Prototype 容器则用于管理非单例对象,可以根据需要创建多个实例。 3. **...
12. **最佳实践**:提供了一些关于如何有效使用Spring IoC的最佳实践和示例,以避免常见的设计陷阱。 通过学习上述知识点,开发者不仅可以理解Spring IoC的基本概念,还能熟练运用到实际项目中,提升项目的质量和可...
此外,文章可能还会涵盖Guice与其他依赖注入框架(如Spring)的对比,以突出Guice的轻量化和灵活性。 总之,Guice是一个强大的工具,能帮助开发者构建松散耦合、易于测试和维护的Java应用。通过深入学习和实践,你...
### 依赖注入实战:关键技术与最佳实践 #### 一、依赖注入概述 依赖注入(Dependency Injection,简称DI)是...本书特别强调了实践中可能会遇到的问题、陷阱及最佳实践,旨在帮助开发者更好地应对实际开发中的挑战。
同时,附带的文件如"51培训网.txt"和"C C++ VC++ Java培训 Java技术 Java编程 DOTNET技术 DOTNET编程 Struts Hibernate Spring - 程序员之家.url"等,可能提供了相关的学习资源链接,可以帮助读者进一步扩展Java和...
Java开发中的23种设计模式,是软件工程领域内一种高度提炼的最佳实践,旨在...无论是初学者还是有经验的开发者,都能从中受益,因为它们提供了经过验证的解决方案,帮助避免常见的设计陷阱,促进代码的复用性和扩展性。