`

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?

相关推荐

    面向对象初学者必须掌握的几种设计模式

    观察者模式 Observer:Swing中的事件模型 工厂模式 Factory:在JDK中遍地都是,比如JDBC、JNDI等,是学习Spring的基础 命令模式 Command:Struts框架的基石 单例模式 Singleton:最简单的设计模式,大量...

    Spring-Reference_zh_CN(Spring中文参考手册)

    6.8.1. 在Spring中使用AspectJ来为domain object进行依赖注入 6.8.1.1. @Configurable object的单元测试 6.8.1.2. 多application context情况下的处理 6.8.2. Spring中其他的AspectJ切面 6.8.3. 使用Spring IoC来...

    Spring中文帮助文档

    6.8.1. 在Spring中使用AspectJ进行domain object的依赖注入 6.8.2. Spring中其他的AspectJ切面 6.8.3. 使用Spring IoC来配置AspectJ的切面 6.8.4. 在Spring应用中使用AspectJ加载时织入(LTW) 6.9. 更多资源 7...

    spring.net中文手册在线版

    Spring.NET以Java版的Spring框架为基础,将Spring.Java的核心概念与思想移植到了.NET平台上。 第一章 序言 第二章 简介 2.1.概述 2.2.背景 2.3.模块 2.4.许可证信息 2.5.支持 第三章 背景 3.1.控制反转 第...

    DSE_Java_Singleton:小型Java程序,用于说明DSE Java驱动程序的基本功能

    将此程序与DataStax DSE Java驱动程序手册中提供的链接一起使用,以初步了解创建程序和设置DSE会话。 背景 在此示例中,DSE会话(您将通过其连接到DSE的对象)已设置为单例类。 在我们的示例程序中, Session类用于...

    spring-beans.zip

    Spring beans 是那些形成Spring应用的主干的java对象。它们被Spring IOC容器初始化,装配,和管理。这些beans通过容器中配置的元数据创建。比如,以XML文件中&lt;bean/&gt; 的形式定义。Spring 框架定义的beans都是单件...

    spring框架技术+第2天+xmind思维导图

    总结,我们会选择第一种方式,因为spring的存在就是要消除工厂模式,因为工厂本身就会在每次调用时new出对象,只是把new的工作换了个地方而已。bean作用域singleton prototype;bean作用域request session global...

    java注解源码-Spring-Framework-1:JavaSpring使用注释和Java源代码配置

    在这个项目中,我使用注释和Java代码配置创建了Spring项目。 运行应用程序 步骤1.安装Tomcat服务器并将其与IDE连接 第2步。添加lib文件夹中的Jar文件- Right click on Main project -&gt; Properties-&gt; Java Build Path...

    Spring 2.0 开发参考手册

    6.8.1. 在Spring中使用AspectJ来为domain object进行依赖注入 6.8.2. Spring中其他的AspectJ切面 6.8.3. 使用Spring IoC来配置AspectJ的切面 6.8.4. 在Spring应用中使用AspectJ Load-time weaving(LTW) 6.9. ...

    基于java的企业级应用开发:Bean的作用域.ppt

    * * * * Bean的作用域 作用域的种类 Spring 4.3中为Bean的实例定义了7种作用域,如下表所示: 注意:在上表7种作用域中,singleton和prototype是最常用的两种作用域。 在Spring配置文件中,可以使用元素的scope属性...

    Spring API

    2. Spring 2.0和 2.5的新特性 2.1. 简介 2.2. 控制反转(IoC)容器 2.2.1. 新的bean作用域 2.2.2. 更简单的XML配置 2.2.3. 可扩展的XML编写 2.2.4. Annotation(注解)驱动配置 2.2.5. 在classpath中自动搜索组件...

    design-patterns-spring-boot:Spring引导中的设计模式

    弹簧靴中的设计模式 该存储库是一个简单的spring boot应用程序,演示了一些设计模式: 辛格尔顿 控制者 厂 战略 代理 观察者 面向方面的编程 该演示应用程序从2个不同的银行的网站(可以添加更多的银行)中检索...

    spring chm文档

    6.8.4. 在Spring应用中使用AspectJ Load-time weaving(LTW) 6.9. 其它资源 7. Spring AOP APIs 7.1. 简介 7.2. Spring中的切入点API 7.2.1. 概念 7.2.2. 切入点实施 7.2.3. AspectJ切入点表达式 7.2.4. ...

    java三大框架

    Spring能消除在许多工程中常见的对Singleton的过多使用。根据我的经验,这是一个很大的问题,它降低了系统的可测试性和面向对象的程度。 通过一种在不同应用程序和项目间一致的方法来处理配置文件,Spring能消除...

    Spring.3.x企业应用开发实战(完整版).part2

    Spring3.0是Spring在积蓄了3年之久后,隆重推出的一个重大升级版本,进一步加强了Spring作为Java领域第一开源平台的翘楚地位。  Spring3.0引入了众多Java开发者翘首以盼的新功能和新特性,如OXM、校验及格式化框架...

    Spring面试题

    在典型的面向对象开发方式中,可能要将日志记录语句放在所有方法和 Java 类中才能实现日志功能。在 AOP 方式中,可以反过来将日志服务模块化,并以声明的方式将它们应用到需要日志的组件上。当然,优势就是 Java 类...

    word源码java-java-knowledge-collection:Java核心知识点梳理

    单例模式(Singleton) 简单工厂模式(Simple Factory) 工厂方法模式(Factory Method) 抽象工厂模式(Abstract Factory) 建造者模式(Builder) 原型模式(Prototype) 结构型 适配器模式(Adapter) 桥接模式...

    JavaNote:java es番石榴jdk jdk8 jsonLombokmd线程jvm spring mvc vertx设计模式风暴

    请叫我大师兄 Java Note ...单例模式(Singleton Pattern) 建造者模式(Builder Pattern) 原型模式(Prototype Pattern) 结构型模式 适配器模式(Adapter Pattern) 桥接模式(Bridge Pattern) 过滤器模式(Fi

    java学习整理文档.docx

    java 学习整理文档 Spring框架并没有对单例bean进行任何多线程的封装处理。关于单例bean的线程安全和并发问题需要开发者自行去搞定 最浅显的解决办法就是将多态bean的作用域由“singleton”变更为“prototype”或者...

Global site tag (gtag.js) - Google Analytics