spring singleton scope与singleton pattern的区别

单态定义:
    Singleton模式主要作用是保证在Java应用程序中,一个类Class只有一个实例存在。

在很多操作中,比如建立目录 数据库连接都需要这样的单线程操作。

还有, singleton能够被状态化;
这样,多个单态类在一起就可以作为一个状态仓库一样向外提供服务,比如,你要论坛中的帖子计数器,每次浏览一次需要计数,单态类能否保持住这个计数,并且
能synchronize的安全自动加1,如果你要把这个数字永久保存到数据库,你可以在不修改单态接口的情况下方便的做到。

另外方面,Singleton也能够被无状态化。提供工具性质的功能,Singleton模式就为我们提供了这样实现的可能。使用Singleton的好处还在于可以节省内存,因为它限制了实例的个数,有利于Java垃圾回收(garbage
collection)。                 
    我们常常看到工厂模式中类装入器(class loader)中也用Singleton模式实现的,因为被装入的类实际也属于资源。

如何使用?
一般Singleton模式通常有几种形式:

饱汉式

public class Singleton {

  private Singleton(){}

  //在自己内部定义自己一个实例,是不是很奇怪?
    //注意这是private 只供内部调用

  private static Singleton instance = new Singleton();

  //这里提供了一个供外部访问本class的静态方法,可以直接访问  
    public static Singleton getInstance() {
        return instance;   
    }
}

饿汉式

public class Singleton {

  private static Singleton instance = null;
    public static synchronized Singleton getInstance();
    if (instance==null){
                             

instance=new Singleton();
        return instance;   

}

}

使用Singleton.getInstance()可以访问单态类。

上面第二中形式是lazy initialization,也就是说第一次调用时初始Singleton,以后就不用再生成了。

注意到lazy initialization形式中的synchronized,这个synchronized很重要,如果没有synchronized,那么使用getInstance()是有可能得到多个Singleton实例。关于lazy
                 initialization的Singleton有很多涉及double-checked locking (DCL)的讨论,有兴趣者进一步研究。

一般认为第一种形式要更加安全些。

使用Singleton注意事项
    有时在某些情况下,使用Singleton并不能达到Singleton的目的,如有多个Singleton对象同时被不同的类装入器装载;在EJB这样的分布式系统中使用也要注意这种情况,因为EJB是跨服务器,跨JVM的。

我们以SUN公司的宠物店源码(Pet Store 1.3.1)的ServiceLocator为例稍微分析一下:
    在Pet
Store中ServiceLocator有两种,一个是EJB目录下;一个是WEB目录下,我们检查这两个ServiceLocator会发现内容差不
多,都是提供EJB的查询定位服务,可是为什么要分开呢?仔细研究对这两种ServiceLocator才发现区别:在WEB中的
ServiceLocator的采取Singleton模式,ServiceLocator属于资源定位,理所当然应该使用Singleton模式。但是
在EJB中,Singleton模式已经失去作用,所以ServiceLocator才分成两种,一种面向WEB服务的,一种是面向EJB服务的。

Singleton模式看起来简单,使用方法也很方便,但是真正用好,是非常不容易,需要对Java的类 线程 内存等概念有相当的了解。

总之:如果你的应用基于容器,那么Singleton模式少用或者不用,可以使用相关替代技术。

所有的业务对象中的成员变量如,在Dao中的xxxDao,或controller中的xxxService,都会被多个线程共享,那么这些对象不会出现同步问题吗,比如会造成数据库的插入,更新异常?

xxxDao的同步问题已经由持久化框架mybatis或hibernate的封装不用担心【其解决方案很有可能就是使用ThreadLocal,见下面】;而我们注入并实例化xxxService只是为了调用xxxService的方法,不会引起同步问题;private static final类型的变量是不会改变的;最好尽量避免全局static类型的变量,防止多线程修改,引起同步问题。

当使用ThreadLocal维护变量[仅仅是变量,因为线程同步的问题就是成员变量的互斥访问出问题]时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。原理概念:为每一个使用该变量的线程都提供一个变量值的副本,是每一个线程都可以独立地改变自己的副本,而不会和其它线程的副本冲突。从线程的角度看,就好像每一个线程都完全拥有该变量。【每个线程其实是改变的是自己线程的副本,而不是真正要改变的变量,所以效果就是每个线程都有自己的,“这其实就将共享变相为人人有份!”】 虽然使用ThreadLocal会带来更多的内存开销,但这点开销是微不足道的。因为保存在ThreadLocal中的对象,通常都是比较小的对象。

实体bean从客户端传递到后台的controller-->service-->Dao,这一个流程中,他们这些对象都是单例的,那么这些单例的对象在处理我们的传递到后台的实体bean会出问题吗?

实体bean不是单例的,并没有交给spring来管理,每次只是手动的new出来的【如EMakeType et = new EMakeType();】,所以即使那些处理我们提交数据的业务处理类是被多线程共享的,但是他们处理的数据并不是共享的,数据是每一个线程都有自己的一份,所以在数据这个方面是不会出现线程同步方面的问题的;

refer to:Spring中Singleton模式的线程安全

spring singleton scope与singleton pattern的区别

一:对于Spring中实现Singleton模式,是以IOC容器为单位(就是说在这个容器里面bean实现Singleton),换句话说,一个JVM可能有多个IOC容器,而在这个容器里实现了singleton bean,
而Java中实现Singleton模式而言,只有一个JVM,jvm中某个class只有一个实例

二:singleton模式中,singleton的class在整个JVM中只有一个instance,Spring的Bean,你可以一个class配置多个Bean,这个class就有了多个instance。这个singleton是指在spring容器中,这个Bean是单实例的,是线程共享的。所以要求这些类都是线程安全的。也就是说,不能出现修改Bean属性的方法,当然除了设值得那些setter。只要满足线程安全,这些bean都可以用singleton。而且我们在绝大多数使用上,也是这样用的,包括dao,service。
    Beanfactory是Spring初始以静态方式载入的,Spring的单例IOC是基于容器级的,所以这你都不用担心与考虑.

spring singleton scope与singleton pattern的区别,布布扣,bubuko.com

时间: 2024-12-19 10:08:49

spring singleton scope与singleton pattern的区别的相关文章

Spring 循环引用 ——理解singleton与prototype初始化的区别

所谓的循环引用,就是A依赖B,B又依赖A,A与B两个对象相互持有.像下面这种情况: class A { B b; public A(B b) { this.b=b; } } class B { A a; public B(A a ) { this.a=a; } } 我们知道spring在获取对象或者在加载的时候,触发依赖注入.例如触发A对象的依赖注入,发现需要B对象,而此时B还没有初始化,就去实例化B对象,而又需要A对象,这样就进入了一种死循环状态,有点像操作系统里面的死锁.似乎这种情况发生了,

spring中scope作用域(转)

摘自 http://www.cnblogs.com/qq78292959/p/3716827.html 今天研究了一下scope的作用域.默认是单例模式,即scope="singleton".另外scope还有prototype.request.session.global session作用域.scope="prototype"多例.再配置bean的作用域时,它的头文件形式如下: 如何使用spring的作用域: <bean id="role&quo

spring中scope(作用越)理解

今天总结了一下spring中作用域scope的用法.在spring中作用域通过配置文件形式的用法如下. <bean id="role" class="spring.chapter2.maryGame.Role" scope="singleton"/> 一. 在spring 中常用的作用域有单例模式(singleton),和多例模式(prototype) 1.当一个bean的 作用域设置为singleton, 那么Spring IOC容

Spring Bean Scope

In Spring, bean scope is used to decide which type of bean instance should be return from Spring container back to the caller. 5 types of bean scopes supported : singleton – Return a single bean instance per Spring IoC container prototype – Return a

Spring中&lt;ref local=&quot;&quot;/&gt;与&lt;ref bean=&quot;&quot;/&gt;区别

小 Spring中<ref local=""/>与<ref bean=""/>区别 (2011-03-19 19:21:58) 转载▼ 标签: 杂谈   <ref local="xx"/>  用"local"属性指定目标其实是指向同一文件内对应"id"属性值为此"local"值的索引"local"属性的值必须和目标bean的id属性

Spring的scope=&quot;prototype&quot;属性

Spring的scope="prototype"属性 可以利用容器的scope="prototype"来保证每一个请求有一个单独的Action来处理, 避免struts中Action的线程安全问题.这句话怎么理解呢如果用单例方式会有什么样的结果呢? spring 默认scope 是单例模式这样只会创建一个Action对象每次访问都是同一个Action对象,数据不安全struts2 是要求 每次次访问 都对应不同的Action scope="prototyp

spring中classpath和classpath*的配置区别

转自:http://www.micmiu.com/j2ee/spring/spring-classpath-start/ —————————————————————————————————————————— 在使用spring时,经常会看到类似 classpth:.classpath*: 这样的前缀,不管是加载spring xml配置文件还是其配置文件中加载资源文件都会看到这两种前缀配置,其实这两种前缀是有区别的,下面将举例详细解释. [一].测试项目准备 我们以spring中加载propert

spring中bean的singleton属性

1.  UserDao.java package com.lxh.springSingleton; public interface UserDao { // 保存User public void save(); } 2.  UserDaoImpl.java package com.lxh.springSingleton; public class UserDaoImpl implements UserDao { @Override public void save() { System.out

Spring 作用域 scope

spring的作用域将对Bean的生命周期和创建方式产生影响.  主要分为五种类型的作用域 singleton (默认)在spring IOC容器中仅存在一个Bean实例,Bean以单实例的方式存在. prototype 每次从容器中调用Bean时,都返回一个新的实例,即每次调用getBean()时,相当于执行new XxxBean()的操作. request 每次HTTP请求都会创建一个新的Bean,该作用域仅适用于webApplicationContext环境. session 同一个HTT