如何在春天中自定义范围的方法示例

  

大家对于春天的范围应该都不会默认。所谓的范围,字面理解就是“作用域”,“范围”,如果一个bean的范围配置为singleton,则从容器中获取bean返回的对象都是相同的;如果范围配置为原型,则每次返回的对象都不同。

  

一般情况下,春天提供的范围都能满足日常应用的场景。但如果你的需求极其特殊,则本文所介绍自定义范围合适你。

  


  

  

默认时,所有Spring bean都是的单例的,意思是在整个春天应用中,bean的实例只有一个。可以在bean中添加范围属性来修改这个默认值.scope属性可用的值如下:
  

  

           范围   描述               单例   每个春容器一个实例(默认值)         原型   允许bean可以被多次实例化(使用一次就创建一个实例)         请求   定义bean的范围是HTTP请求。每个HTTP请求都有自己的实例。只有在使用有网络能力的弹簧上下文时才有效         会话   定义bean的范围是HTTP会话。只有在使用有网络能力的Spring ApplicationContext才有效         应用程序   定义了每个ServletContext一个实例         websocket   定义了每个WebSocket一个实例。只有在使用有网络能力的Spring ApplicationContext才有效            

  

如果上述范围仍然不能满足你的需求,春天还预留了接口,允许你自定义范围。

  


  

  

<代码> org.springframework.beans.factory.config.Scope 接口用于定义范围的行为:

        包org.springframework.beans.factory.config;      进口org.springframework.beans.factory.ObjectFactory;   进口org.springframework.lang.Nullable;      公共接口范围{      对象得到(字符串名称,ObjectFactory<& # 63;比;objectFactory);      @Nullable   删除对象(字符串名称);      空白registerDestructionCallback(字符串名称,可调);      @Nullable   字符串对象resolveContextualObject(关键);      @Nullable   字符串getConversationId ();      }      

一般来说,只需要重新获取和删除方法即可。

  


  

  

现在进入实战环节。我们要自定义一个春天没有的范围,该范围将bean的作用范围限制在了线程内,即相同线程内的bean是同个对象,跨线程则是不同的对象。

  

<强> 1。定义范围
  

  

要自定义一个春天的范围,只需实现org.springframework.beans.factory.config.Scope接口。代码如下:

        包com.waylau.spring.scope;      进口java.util.HashMap;   进口java.util.Map;      进口org.springframework.beans.factory.ObjectFactory;   进口org.springframework.beans.factory.config.Scope;/* *   *线范围。   *   * @since 1.0.0 2019年2月13日   * @author & lt; a href=" https://waylau.com " rel=巴獠縩ofollow”rel=巴獠縩ofollow”rel=巴獠縩ofollow”rel=巴獠縩ofollow”rel=巴獠縩ofollow”祝辞Lau   */公共类ThreadScope实现范围{      私人最终ThreadLocal比;threadLoacal=new ThreadLocal在(){   @Override   保护Map<字符串,Object>initialValue () {   返回新HashMap<字符串,Object> ();   }   };      公共对象(字符串名称,ObjectFactory<& # 63;比;objectFactory) {   Object> Map<字符串;范围=threadLoacal.get ();   对象obj=scope.get(名称);//不存在则放入ThreadLocal   如果(obj==null) {   obj=objectFactory.getObject ();   范围。把(名称、obj);      system . out。println(“不存在”+名字+”;hashCode:“+ obj.hashCode ());   其他}{   system . out。println(“存在”+名字+”;hashCode:“+ obj.hashCode ());   }      返回obj;   }      公共对象删除(字符串名称){   Object> Map<字符串;范围=threadLoacal.get ();   返回scope.remove(名称);   }      公共字符串getConversationId () {   返回null;   }      公共空间registerDestructionCallback(字符串arg0, Runnable __arg1) {   }      公共对象resolveContextualObject(字符串arg0) {   返回null;   }      }      

在上述代码中,threadLoacal用于做线程之间的数据隔离。换言之,threadLoacal实现了相同的线程相同名字的bean是同一个对象;不同的线程的相同名字的bean是不同的对象。

如何在春天中自定义范围的方法示例