`

Spring中的Singleton模式和Java中的Singleton模式

    博客分类:
  • J2EE
阅读更多
对于Spring中实现Singleton模式,是以IOC容器为单位,换句话说,一个JVM可能有多个IOC容器,而Java中实现Singleton而言,只有一个JVM。所以说,Spring中实现的Singleton模式与Java中的Singleton设计模式有点不同。
此外,spring singleton的含义是在一个spring 上下文中保持单态。
所以singleton模式中,singleton的class在整个JVM中只有一个instance,Spring的Bean,你可以一个class配置多个Bean,这个class就有了多个instance。这个singleton是指在spring容器中,这个Bean是单实例的,是线程共享的。所以要求这些类都是线程安全的。也就是说,不能出现修改Bean属性的方法,当然除了设值得那些setter。只要满足线程安全,这些bean都可以用singleton。而且我们在绝大多数使用上,也是这样用的,包括dao,service。

Beanfactory是Spring初始以静态方式载入的,Spring的单例IOC是基于容器级的,所以这你都不用担心与考虑.

--应用中对象有两种,行为对象和数据对象,行为对象都要求是线程安全的!也就是允许单例的, 不管是dao 还是 service 对象,都是行为对象,行为对象不应该引用非线程安全的对象做成员量,同时在应用外部的资源(如文件,数据库连接,session)时,要先保证对这些东西的访问是做了并发控制的!

  对于spring来讲,<bean scope="singleton"/>或<bean singleton="true"/>都是保证对同一sesionfactory bean是单例的,也就是所谓 sessionfactory 范围的.

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

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

Authentication auth = SecurityContextHolder.getContext().getAuthentication();   
<script>render_code();</script>

我可以很容易在系统任意一层得到用户的信息,而不用把用户信息在参数里传来传去,(这也是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();   
}   
<script>render_code();</script>


这样在其他的Service和Dao类里可以通过
super.getUserContext(), super.getUserInfo()   
<script>render_code();</script>


来得到用户的信息,这也为问题的产生提供了温床。请看如下代码:
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   
    }   
}       
<script>render_code();</script>


这段代码在单元测试的时候不会用任何问题,但是在多用户测试的情况下,你会发现任何调用SomeService里someMethod()方法的userID和userName都是同一个人,也就是第一个登陆的人的信息。
其根本原因是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   
    }
}
1
1
分享到:
评论
2 楼 phoenix5870 2015-11-19  
默认就是singleton的。
1 楼 撼地神牛 2011-09-08  
难道你吧 service dao 都设置成了 singleton?

相关推荐

    设计模式-Java语言中的应用(pdf)

    另外,Spring框架中的依赖注入(Dependency Injection)和面向切面编程(Aspect-Oriented Programming)也是设计模式的典型应用,它们通过控制反转和切面分离,极大地提高了代码的可测试性和可维护性。 此外,设计...

    Java EE设计模式:Spring企业级开发最佳实践

    在 Spring 中,观察者模式广泛应用于事件驱动编程中,例如,在 Spring MVC 中,使用观察者模式来处理请求和响应。 4.MVC Pattern:模型视图控制器模式,分离应用程序的关注点,实现高内聚、低耦合的设计。 在 ...

    大话设计模式--Singleton(单例模式)

    例如,Spring框架中的ApplicationContext就是通过单例模式来管理所有bean的。然而,需要注意的是,过度使用单例可能导致系统设计过于紧密,不利于测试和扩展,因此在设计时应权衡利弊。 总之,单例模式是一种常用的...

    Spring中的singleton和prototype的实现

    Spring中的singleton和prototype的实现 Spring框架中,bean的作用域是指在容器中bean的实例化和生命周期管理。其中,singleton和prototype是两个最基本的bean作用域。本文将详细介绍Spring中的singleton和...

    设计模式:Java语言中的应用.zip

    在Java中,设计模式的应用不仅限于这些基础模式,还包括对框架的理解和使用,如Spring框架中的依赖注入(Dependency Injection,DI)和控制反转(Inversion of Control,IoC)就是对工厂模式和策略模式的扩展。...

    Java深入分析Spring源码

    3、单例模式(Singleton):Spring 中的单例模式用于保证一个类仅有一个实例,并提供一个访问它的全局访问点。 在 Spring 中,设计模式的应用遵循六大原则: 1、开闭原则(OpenClosePrinciple):对扩展开放,对...

    设计模式之Singleton(单态)

    3. **状态共享**:可将状态存储在Singleton中,为多个对象提供统一的访问点,简化状态管理。 4. **控制实例化过程**:在特定条件下实例化,如初始化资源、设置配置等。 ### 使用Singleton的注意事项 1. **线程安全...

    Singleton 设计模式

    1. **反模式**:在某些设计原则(如面向对象的原则)中,Singleton 被视为一种反模式,因为它限制了类的扩展和复用。 2. **测试困难**:由于 Singleton 是全局的,它可能难以在单元测试中进行隔离,增加了测试的复杂...

    java设计模式中英文各种版本打包下载 学习设计模式必备材料

    1. 创建型模式(Creational Patterns):如单例模式(Singleton)、工厂模式(Factory Method)、抽象工厂模式(Abstract Factory)、建造者模式(Builder)和原型模式(Prototype)。它们主要处理对象的创建,帮助...

    Java 企业设计模式

    如Spring框架中的AOP(面向切面编程)利用代理模式实现方法的拦截和增强,提供事务管理、日志记录等功能;DAO(数据访问对象)模式则通过封装数据库操作,降低了业务逻辑与数据存储间的耦合。 行为型模式在多线程...

    Java中Spring获取bean方法小结

    在Java开发中,Spring框架是不可或缺的一部分,它提供了一个强大的依赖注入(DI)和面向切面编程(AOP)的容器。Spring的核心在于其BeanFactory和ApplicationContext,它们使得对象的管理和装配变得简单。这里我们将...

    singleton demo

    本示例"SingletonDemo"将深入探讨如何在Java中实现Singleton模式。 首先,Singleton模式的核心在于限制类的实例化过程。通常,我们通过私有化构造函数来防止直接实例化。下面是一个基本的Singleton模式实现: ```...

    Spring 5 Design Patterns.pdf

    书中通过讲解诸如代理(Proxy)、单例(Singleton)、模板方法(Template Method)等经典的设计模式来帮助读者更好地理解和运用Spring框架的功能。 #### 二、设计模式简介 设计模式是在软件开发过程中经过长时间...

    Spring设计思想.ppt

    Spring框架是Java开发中广泛应用的轻量级框架,它的设计思想体现了软件工程的诸多原则,如依赖注入、面向切面编程等。其中,Spring的核心设计理念体现在对两种基本设计模式的实现上:工厂模式和单态模式。 首先,...

    spring6pdf详细讲解

    在 Spring 中,GoF 之 factory 模式是指工厂模式、抽象工厂模式和简单工厂模式等。这些模式使得开发者可以编写更加灵活和可维护的代码。 在 Spring 中,JdbcTemplate 是框架的 JDBC 模块之一。 JdbcTemplate 提供了...

    设计模式:Java语言中的应用

    除了上述经典设计模式,还有一些现代设计原则和模式,如依赖注入(Dependency Injection),在Java中可以通过Spring框架实现。模版方法模式(Template Method)定义了操作中的算法骨架,而允许子类重新定义某些步骤...

    Java EE设计模式:Spring企业级开发最佳实践_JavaEE_企业应用开发_

    《Java EE设计模式:Spring企业级开发最佳实践》是一本深度探讨如何在企业级Java应用程序中有效运用设计模式的著作。这本书聚焦于Spring框架,它作为Java EE领域中最为广泛使用的开源框架之一,极大地简化了企业级...

    java与模式,设计模式的应用

    1. 创建型模式(Creational Patterns):如单例模式(Singleton)、工厂方法模式(Factory Method)、抽象工厂模式(Abstract Factory)、建造者模式(Builder)和原型模式(Prototype)。这些模式主要关注对象的...

    设计模式:Java语言中的应用.rar

    综上所述,“设计模式:Java语言中的应用.rar”涵盖了Java开发中设计模式的广泛应用和深入解析,对于提升Java开发人员的设计能力和技术水平具有极高的价值。通过学习和掌握这些模式,开发者可以编写出更加优雅、灵活...

    设计模式与JAVA

    创建型模式关注对象的创建,如单例模式(Singleton)、工厂模式(Factory Method)和建造者模式(Builder)。它们提供了一种方式来控制实例化过程,使得系统更加灵活,易于扩展。 结构型模式则关注如何将对象和类...

Global site tag (gtag.js) - Google Analytics