- 浏览: 604009 次
- 性别:
- 来自: 北京
最新评论
-
黑色幽默_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 1395<plugin> <group ... -
uninstall mysql completely in my Mac X 10.6
2011-08-07 12:19 1191sudo rm /usr/local/mysql ... -
my vimrc
2011-05-14 11:02 1712copy from http://www.vi-improve ... -
使用HSQLDB来作EJB3 EntityBean到Unit Test要点
2010-01-20 17:17 2109add <property name=" ... -
user xrandr to change my desktop's resolution
2009-12-16 17:04 1680xrandr --newmode "1280x ... -
XSS的关键之列表
2009-10-11 17:20 1831//this field are used tp esc ... -
python查看方法帮助(from dive into python)
2009-09-30 11:31 2618def info(object, spanding=10, c ... -
selenium 测试ajax的关键
2009-01-20 18:26 42271: waitForCondition(contidtion, ... -
RichFaces 手记
2008-10-07 15:46 0安装,除了richfaces 下载包中的jar( " ... -
代码检查工具
2008-09-25 11:48 2558findBugs, PMD, CheckStyle find ... -
CI工具hudson
2008-09-24 17:04 3112CI工具除了hudson,还有很多,例如CruiseContr ... -
创建solaris package step by step
2008-09-24 11:27 1920原文地址:http://www.ibiblio.org/pub ... -
什么是SVR4?我们为什么要选择SVR4?
2008-09-23 14:13 4955http://www.lslnet.com/linux/f/d ... -
IPS 中的pkg command学习笔记
2008-09-22 17:18 1843pkg(1): 使用pkg(1)来创建一个镜像,安装,升级,管 ... -
On Board前的学习计划
2008-09-18 09:37 15161:在virtual box 上虚拟一个OpenSolaris ... -
YUI Grid CSS的优雅设计
2008-09-02 22:38 2813最近加入了一个GAE的项目cpedialog,该项目的前端布局 ... -
我很懒,但是懒人有懒办法
2008-08-18 17:06 1798今天要使用jackrabbit做个小东西,上apache一看, ... -
当XPath遇上NameSpace
2008-07-23 19:39 6562在jdk5.0中,已经包含了对Xpath的支持,可一通过下面的 ... -
ubuntu下安装ipmsg-飞鸽传书
2008-07-21 09:32 28791 先下载 源码 下载的是gnome2版本的源码 http ... -
sudo 执行时无密码(不安全)
2008-07-17 17:18 2211sudo visudo root ALL=(ALL) ...
相关推荐
Singleton模式意味着每个Bean在Spring容器中只会存在一个实例。当你通过`ApplicationContext`获取一个配置为`scope="singleton"`的Bean时,无论你调用`getBean`多少次,都会返回同一个对象实例。例如,在`UserDao`的...
首先,`singleton`是Spring默认的作用域,意味着当Spring容器初始化时,对于每个具有`singleton`作用域的Bean,它只会创建一个唯一的实例。这个实例在整个应用程序生命周期中被共享,无论何时请求该Bean,Spring都会...
Spring中的singleton和prototype的实现 Spring框架中,bean的作用域是指在容器中bean的实例化和生命周期管理。其中,singleton和prototype是两个最基本的bean作用域。本文将详细介绍Spring中的singleton和...
Spring 还提供了多种范围的 Bean,包括 singleton、prototype 等。 Spring 的 IoC 容器是框架的核心组件,它负责管理和实例化 Bean,并提供了依赖注入和控制反转的功能。 Spring 的 IoC 容器可以自动装配 Bean,...
### C++中实现Singleton模式的关键知识点 #### 一、Singleton模式简介 Singleton模式是一种常用的软件设计模式,旨在确保一个类只有一个实例,并提供一个全局访问点。这种模式在系统中经常被用于控制对共享资源...
Spring Bean作用域属性singleton和prototype的区别详解 Spring Framework中,Bean的作用域属性是指Bean实例的生命周期和作用域。Spring提供了五种作用域:singleton、prototype、request、session和global session...
Singleton模式是一种常用的软件设计模式,它保证一个类只有一个实例,并提供一个全局访问点。这个模式在许多场景下非常有用,例如当系统只需要一个共享的配置对象或者管理某种资源时。Singleton模式的核心特点是单例...
**C++实现的Singleton模式详解** Singleton模式是一种常用的软件设计模式,它保证一个类只有一个实例,并提供一个全局访问点。这种模式在很多场景下都非常有用,例如管理共享资源,如数据库连接池,或者确保某个...
在Qml中,我们可以通过Qt的Singleton组件来实现这一模式。 首先,让我们理解单例模式的基本概念。在软件工程中,单例模式保证一个类只有一个实例,并提供一个全局访问点。这个设计模式在许多场景下都很实用,比如...
2. **Spring Bean**:介绍Spring容器如何创建、初始化、配置和管理Bean,以及Bean的作用域(如Singleton、Prototype等)。 3. **AOP**:讲解面向切面编程的概念,如何在不修改源代码的情况下,实现对程序行为的统一...
**Singleton设计模式** Singleton设计模式是软件工程中最常用的设计模式之一,它的主要目的是确保一个类只有一个实例,并提供全局访问点。在Java中,Singleton模式的实现有多种方式,每种方式都有其优缺点,我们将...
默认情况下,Spring容器会为每个Bean创建一个实例,若需实现单例,只需在XML配置中设置`scope="singleton"`,或在注解中使用`@Scope("singleton")`。 16. **Spring中如何处理异常?** Spring支持异常翻译,将底层...
4. Bean的作用域:掌握singleton、prototype、request、session等不同作用域的概念及其应用场景。 三、AOP(面向切面编程) 1. AOP基础:理解AOP的基本概念,包括切面、通知、连接点、切入点表达式等。 2. Spring ...
单例模式(Singleton Pattern)是软件设计模式中的一种,它保证一个类只有一个实例,并提供一个全局访问点。这种模式在很多场景下非常有用,比如控制资源的唯一性、全局配置对象或者缓存服务等。本篇文章将深入探讨...
- **Singleton Beans的懒加载**:如果Bean的scope为singleton,并且在XML配置中没有设置`lazy-init="true"`,那么Spring容器在启动时就会实例化这些Bean。 - **Prototype Beans的每次请求创建**:scope为prototype...
Spring框架是Java开发中广泛应用的轻量级框架,它的设计思想体现了软件工程的诸多原则,如依赖注入、面向切面编程等。其中,Spring的核心设计理念体现在对两种基本设计模式的实现上:工厂模式和单态模式。 首先,...
Spring框架广泛运用了多种设计模式,如工厂模式(BeanFactory)、单例模式(Singleton)、代理模式(AOP代理)、装饰器模式(BeanPostProcessor)等,这些模式的运用使得Spring具有高度的灵活性和可扩展性。...
Singleton 单例模式是软件设计模式中的一种,它限制了类的实例化过程,确保一个类在整个系统中只有一个实例存在。这种模式常用于系统资源管理,比如数据库连接、线程池或者缓存服务等,因为这些资源往往需要全局共享...