Spring Singleton的陷阱

2016-02-19 20:08 5 1 收藏

最近很多朋友喜欢上设计,但是大家却不知道如何去做,别担心有图老师给你解答,史上最全最棒的详细解说让你一看就懂。

【 tulaoshi.com - 编程语言 】

  这是一个真实的案例,我们在项目中使用Spring和ACEGI,我之所以选择ACEGI,除了它对权限的良好控制外,

  我还看好它的SecurityContextHolder,通过代码

(本文来源于图老师网站,更多请访问https://www.tulaoshi.com/bianchengyuyan/)

  Authentication auth = SecurityContextHolder.getContext().getAuthentication();

  我可以很容易在系统任意一层得到用户的信息,而不用把用户信息在参数里传来传去,(这也是struts的缺点之一)

  但是我在每一次要得到用户信息的时候都写上面的一段代码,未免有些麻烦,所以我在BaseService, BaseDao里都提供了如下方法:

(本文来源于图老师网站,更多请访问https://www.tulaoshi.com/bianchengyuyan/)

  /**//**
   * 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  
      }
  }

来源:https://www.tulaoshi.com/n/20160219/1622854.html

延伸阅读
Spring 是一个开源框架,是为了解决企业应用程序开发复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构答应您选择使用哪一个组件,同时为 J2EE 应用程序开发提供集成的框架。 !-- frame contents -- !-- /frame contents -- 在这篇由三部分组成的 Spring 系列 的第 1 部分中,我将介绍 Spring 框架。我先...
一、功能 保证一个类仅有一个实例。 三、优缺点 Singleton模式是做为"全局变量"的替代品出现的。所以它具有全局变量的特点:全局可见、贯穿应用程序的整个生命期,它也具有全局变量不具备的性质:同类型的对象实例只可能有一个。 四、实现 教科书上的Singleton定义如下: class Singleton { public: static Si...
标签: Web开发
zhipingch 原创     去年初,正好负责一个医药信息系统的设计开发,架构设计时,采用Struts+JDBC(自定义采用适配器模式封装了HashMap动态VO实现的持久层)。后来ajax热潮兴起,正好系统中有很多地方需要和服务器端交互数据,如采购销售系统中的订单头/订单明细等主从表结构的维护。     [color=blue...
标签: Web开发
本文将为您提供关于Spring MVC框架的配置技巧,以帮助管理基于Spring的web应用程序的多个实例。本配置管理主题常被学术界所忽略,但是,这对于现实的web开发尤为重要。本主题并不直接关联任何具体的技术,因此,我们将从最基本的概念开始对这个问题进行说明。下面,我们将根据Spring MVC框架,为基于本技术开发的项目提供一系列的解决方案。 ...
  ANSI C++ 中的 Singleton 实现说难不难,说轻易也不轻易,很多人写 ANSI C++ 的 Singleton class 都有错误。这篇文章讨论怎样在 ANSI c++ 中写 Singleton class, 希望对大家有帮助。   《设计模式》中把 Singleton 写成返回指针: class Singleton{ public:     static Singleton* Instance(...

经验教程

58

收藏

21
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部