美文网首页
bean的作用域

bean的作用域

作者: 熊熊要更努力 | 来源:发表于2017-08-17 21:06 被阅读10次

    当通过spring容器创建一个Bean实例时,不仅可以完成Bean实例的实例化,还可以为Bean指定特定的作用域。Spring支持如下4种作用域:

    • singleton:单例模式,在整个Spring IoC容器中,使用singleton定义的Bean将只有一个实例

    • prototype:原型模式,每次通过容器的getBean方法获取prototype定义的Bean时,都将产生一个新的Bean实例

    • request 请求模式:对于每次HTTP请求,使用request定义的Bean都将产生一个新实例,即每次HTTP请求将会产生不同的Bean实例。只有在Web应用中使用Spring时,该作用域才有效

    • session 会话模式:对于每次HTTP Session,使用session定义的Bean豆浆产生一个新实例。同样只有在Web应用中使用Spring时,该作用域才有效

    单例是默认的作用域.对于易变的作用域,这并不合适.如果选择其他的作用域,要使用@scope注解.
    for example:
    @Compenent
    @Scope(ConfigurableBeanFactory.SCOPE_PROYOTYPE)
    public class notpad
    {}

    基本作用域

    • singleton
      作用域的Bean只会在每个Spring IoC容器中存在一个实例,而且其完整生命周期完全由Spring容器管理。对于所有获取该Bean的操作Spring容器将只返回同一个Bean。
      单例模式:就是私有化构造函数,通过唯一的方法获取对象,并且每次获取为同一对象

        public class Singleton {
        /*1.私有化构造函数*/
        private Singleton() {}
        //2.单例缓存者,惰性初始化,第一次使用时初始化
        private static class InstanceHolder {
        private static final Singleton INSTANCE = new Singleton();
        }
        //3.提供全局访问点
        public static Singleton getInstance() {
        return InstanceHolder.INSTANCE;
            }
        }
      

    以上就实现了一个单例模型

    Spring把模型通过注册表的方式,将Bean缓存起来,先将Bean通过唯一键注册到表中,再通过键来获取他们,Spring的单例模式是通过注册表实现的,而非代码式单例模式,所以是非侵入式的。
    在Spring中,Bean在没有指定作用域的时候,默认是单例模式的。

    Spring中的单例模式.png
    • prototype
      原型模式,每次都是获取新的对象,跟单例模式不一样,Spring不对prototype模式的Bean进行缓存.
    Spring的原型模式.png

    Web应用中的作用域

    Spring提供了3种在Web中的作用域,分别在request、session、globalSession。这些作用域的有效范围分别如下

    • request
      每一次HTTP请求都会产生一个新的bean,这个bean仅在当前request内有效
      针对每次HTTP请求,Spring容器会根据loginAction bean定义创建一个全新的LoginAction bean实例,且该loginAction bean实例仅在当前HTTP request内有效,因此可以根据需要放心的更改所建实例的内部状态,而其他请求中根据loginAction bean定义创建的实例,将不会看到这些特定于某个请求的状态变化。当处理请求结束,request作用域的bean实例将被销毁。

    • session
      每一次HTTP请求都会产生一个新的bean,同时该bean仅在当前session内有效
      针对某个HTTP Session,Spring容器会根据userPreferences bean定义创建一个全新的userPreferences bean实例,且该userPreferences bean仅在当前HTTP Session内有效。与request作用域一样,你可以根据需要放心的更改所创建实例的内部状态,而别的HTTP Session中根据userPreferences创建的实例,将不会看到这些特定于某个HTTP Session的状态变化。当HTTP Session最终被废弃的时候,在该HTTP Session作用域内的bean也会被废弃掉。

    • global session
      全局session有效,这个是针对portlet的web应用的,具体可以看看Portlet是如何定义了全局Session的。这个有效范围是全局portlet Session的生命周期范围内,如果不是portlet的web应用,那么这个等同于session作用域。

    自定义bean装配作用域

    在2.0之后,Spring支持自己定义作用域了(不能覆盖singleton和prototype这两个现有的作用域)只要实现Scope接口就可以。
    我们建立一个线程的scope,该scope在表示一个线程中有效,代码如下:

        import org.springframework.beans.factory.config.Scope;
        public class MyScope implements Scope { 
         private final ThreadLocal threadScope = new ThreadLocal() {
          protected Object initialValue() {
             return new HashMap(); 
          } 
       }; 
    
     public Object get(String name, ObjectFactory objectFactory) { 
         Map scope = (Map) threadScope.get(); 
         Object object = scope.get(name); 
        if(object==null) { 
           object = objectFactory.getObject(); 
           scope.put(name, object); 
         } 
        return object; 
      } 
    
     public Object remove(String name) { 
        Map scope = (Map) threadScope.get(); 
        return scope.remove(name); 
      }
    
      publicvoid registerDestructionCallback(String name, Runnable callback) { 
      }
    
    public String getConversationId() {
       // TODO Auto-generated method stub
        return null;
     } 
    }
    

    相关文章

      网友评论

          本文标题:bean的作用域

          本文链接:https://www.haomeiwen.com/subject/lninrxtx.html