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

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

Spring 内置的 scope

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

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

Scope 接口

org.springframework.beans.factory.config.Scope接口用于定义scope的行为:

package org.springframework.beans.factory.config;import org.springframework.beans.factory.ObjectFactory;import org.springframework.lang.Nullable;public interface Scope { Object get(String name, ObjectFactory> objectFactory);@NullableObject remove(String name);void registerDestructionCallback(String name, Runnable callback); @NullableObject resolveContextualObject(String key);@NullableString getConversationId();}

一般来说,只需要重新 get 和 remove 方法即可。

自定义线程范围内的scope

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

1. 定义scope

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

package com.waylau.spring.scope;import java.util.HashMap;import java.util.Map;import org.springframework.beans.factory.ObjectFactory;import org.springframework.beans.factory.config.Scope;/** * Thread Scope. *  * @since 1.0.0 2019年2月13日 * @author Way Lau */public class ThreadScope implements Scope {private final ThreadLocal> threadLoacal = new ThreadLocal>() { @Overrideprotected Map initialValue() {return new HashMap();}};public Object get(String name, ObjectFactory> objectFactory) {Map scope = threadLoacal.get();Object obj = scope.get(name);// 不存在则放入ThreadLocalif (obj == null) {obj = objectFactory.getObject();scope.put(name, obj);System.out.println("Not exists " + name + "; hashCode: " + obj.hashCode());} else {System.out.println("Exists " + name + "; hashCode: " + obj.hashCode());}return obj;}public Object remove(String name) {Map scope = threadLoacal.get();return scope.remove(name);}public String getConversationId() {return null;}public void registerDestructionCallback(String arg0, Runnable arg1) {}public Object resolveContextualObject(String arg0) {return null;}}

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

同时,我们将对象的hashCode打印了出来。如果他们是相同的对象,则hashCode是相同的。

2. 注册scope

定义一个AppConfig配置类,将自定义的scope注册到容器中去。代码如下:

package com.waylau.spring.scope;import java.util.HashMap;import java.util.Map;import org.springframework.beans.factory.config.CustomScopeConfigurer;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;/** * App Config. * * @since 1.0.0 2019年2月13日 * @author Way Lau */@Configuration@ComponentScanpublic class AppConfig {@Beanpublic static CustomScopeConfigurer customScopeConfigurer() {CustomScopeConfigurer customScopeConfigurer = new CustomScopeConfigurer();Map map = new HashMap();map.put("threadScope

error:lnk2005 已经在*.obj中定义_如何在 Spring 中自定义 scope相关推荐

  1. typescript中函数_如何在TypeScript中合成Canvas动画

    typescript中函数 by Changhui Xu 徐昌辉 如何在TypeScript中合成Canvas动画 (How to Compose Canvas Animations in TypeS ...

  2. swift语言 数组定义_如何在Swift中声明弱引用数组?

    I'd like to store an array of weak references in Swift. The array itself should not be a weak refere ...

  3. 二叉树 迭代 前 中 后_如何在Ruby中使用数组迭代计算二叉树的高度

    二叉树 迭代 前 中 后 Data structures and algorithms are the heart and soul of computer science and software. ...

  4. m 文件 dll matlab 中调用_如何在matlab中调用python程序

    现在python很火,很多代码都是python写的,如果你和我一样,习惯了使用matlab,还想在matlab中调用Python的代码,应该怎么办呢?其中一条思路:首先在matlab中调用系统脚本命令 ...

  5. scala中捕获异常_如何在Scala中引发异常?

    scala中捕获异常 Scala的例外 (Exceptions in Scala) Exceptions are cases or events that occur in the program a ...

  6. scala集合中添加元素_如何在Scala中获得列表的第一个元素?

    scala集合中添加元素 清单 (List) A list is a linear data structure. It is a collection of elements of the same ...

  7. javascript中索引_如何在JavaScript中找到数字在数组中所属的索引

    javascript中索引 Sorting is a very important concept when writing algorithms. There are all kinds of so ...

  8. 在linux中的文件中查找_如何在Linux中查找文件

    在linux中的文件中查找 如果您是Windows用户或OSX的非超级用户,则可能使用GUI查找文件. 您可能还会发现界面有限,令人沮丧或两者兼而有之,并且学会了精于组织事物并记住文件的确切顺序. 您 ...

  9. python中小数_如何在Python中乘以小数

    在Python 3 input中将返回一个字符串.这基本上等同于Python 2中的raw_input.因此,您需要在执行任何计算之前将该字符串转换为数字.并准备好"输入错误"(即 ...

最新文章

  1. 《Java编程思想》笔记13.字符串
  2. python csv库,Python 中导入csv数据的三种方法
  3. 【ECSHOP】格式化商品价格
  4. mysql业务 日志_mysql笔记之日志篇
  5. kerberos 主从安装
  6. Linux C语言 文件操作
  7. MySQL笔记-解决...mysql.sock (13)(两种情况会产生此问题)
  8. sql卡住php-fpm会cpu大涨,排查PHP-FPM占用CPU过高
  9. REX-Ray 了解
  10. MySQL删除主从表数据
  11. Linux Shell基础 Shell的输入重定向和输出重定向
  12. 解决ASP.NET中Redis 每小时6000次访问请求的问题
  13. 有的数字不适合作版本号
  14. 樱花FRP(SAKURA FRP)远程桌面+rdpwrap绕过限制
  15. 联想拯救者笔记本摄像头打不开
  16. 一条wmic命令解决硬盘序列号和mac地址查询
  17. LAMP系列文章之:泛泛而谈LAMP(一)
  18. 董事长和总经理的最大区别
  19. 实时语音趣味变声,大叔变声“妙音娘子”Get一下
  20. 第一行代码Android个人笔记(五)——文件存储

热门文章

  1. 2008年小结,我想,我就从这里开始
  2. Hashmap扩容时出现循环链表(jdk1.8把头插法换成了尾插法的原因)
  3. 设计模式--策略模式--Java实现
  4. 阿里云提示微擎被挂图片木马详解
  5. php的工作模式CGI,FastCGI,PHP-CGI与PHP-FPM(转)
  6. unserialize用法
  7. 正则表达式表示的IP
  8. 提升存储设备的吞吐量
  9. 日结问题解决思路和方式
  10. 关于MySQL优化的几个问题