场景

有个功能需要使用多例的bean来实现,原因如下:
1. 此项目是多Module项目,这里暂且叫做moduleA和moduleB,moduleB的maven里依赖了moduleA,而moduleA又需要调用moduleB,所以我这里是在moduleA中定义了一个接口interface ==Deployer==,在moduleB中写实现类==AppDeployer==。这样就可以通过容器的ApplicationContext.getBean(Deployer.class)获取到对应的实现。
2. moduleB中的实现类==AppDeployer==因为业务需要,定义了局部变量,而且这些局部变量不可被其他线程共享,因此需要将此实现类设置为@Scope("prototype")多例bean。
3. 在moduleA中是如下调用的:
 Deployer deployer = SpringContextUtils.getBean(Deployer.class);executor.execute(() -> deployer.deploy(deployInfo));

测试

因为每次getBean就会创建一个新的bean,担心会造成OOM故障,做了一个多例bean的创建销毁测试。

注:这里是使用了demo用于测试,和上面的场景无关。

  1. 给bean定义初始化方法和销毁方法并打印日志
@Component
@Scope("prototype")
@Slf4j
public class ProtoBean {private int i = 0;public void run() {try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}i++;log.info("bean {} run, i = {}", this, i);}@PostConstructpublic void init() {log.info("init bean");}@PreDestroypublic void destroy() {log.info("destroy bean");}
}
  1. 实现一个接口用于调用这个bean
@Service
public class UserServiceImpl extends ServiceImpl<UserDao, User> implements UserService {@Autowired@Qualifier("executor")private ThreadPoolTaskExecutor executor;@Autowiredprivate ApplicationContext applicationContext;@Overridepublic boolean save(User user) {ProtoBean bean = applicationContext.getBean(ProtoBean.class);executor.execute(() -> {bean.run();});return super.save(user);}
}
  1. 用postman多次调用步骤2的接口,可以看到日志中有打印bean的创建方法日志

  2. 在idea中的Terminal窗口使用jps命令查看进程,结果如下:

> jps
23852 CloudDemoApplication
  1. 使用jmap命令dump文件,文件会生成在当前工程目录下,这里的文件名称为heap.bin
> jmap -dump:format=b,file=heap.bin 23852
Dumping heap to D:\project\cloudDemo\heap.bin ...
Heap dump file created
  1. 使用jhat命令启动服务,可以通过浏览器查看dump文件的详情
> jhat -J-Xmx512m heap.bin
Reading from heap.bin...
Dump file created Mon Aug 15 16:16:53 CST 2022
Snapshot read, resolving...
Resolving 497479 objects...
Chasing references, expect 99 dots...................................................................................................
Eliminating duplicate references...................................................................................................
Snapshot resolved.
Started HTTP server on port 7000
Server is ready.
  1. 使用jmap命令dump文件,文件会生成在当前工程目录下,这里的文件名称为heap.bin
> jmap -dump:format=b,file=heap.bin 23852
Dumping heap to D:\project\cloudDemo\heap.bin ...
Heap dump file created
  1. 浏览器访问link localhost:7000,搜索对应的bean名称并按照图片步骤点击进入即可看到对应的实例信息。可以看到此时有两个bean的实例(这里我调用了两次)

  2. 打开本地的cmd控制台,使用jconsole命令,会弹出窗口,选择当前的java应用,点击“不安全的连接”进入java监视和管理控制台,切换到内存tab页点击GC按钮,等待几秒钟。

10.重复步骤4~8,可以看到实例会被JVM GC回收,但是日志中并没有打印销毁方法

结论

java的bean为多例状态时,如果我们使用getBean的方式获取对象,仍然还是会从容器中创建新的bean实例,但是不负责销毁,而是将此实例交付给JVM进行回收

spring多例的销毁相关推荐

  1. Spring单例的线程安全性

    在Spring中单例bean是在beanfactory中用反射机制动态创建的,被缓存到ioc容器中相对于new了一个对象. 而这些创建的对象class,则是自己创建的. 所以是不是线程安全和Sprin ...

  2. 手动加载spring, ApplicationContext怎么销毁

    手动加载spring, ApplicationContext怎么销毁 AbstractApplicationContext context = new ClassPathXmlApplicationC ...

  3. spring bean初始化及销毁你必须要掌握的回调方法。

    转载自 spring bean初始化及销毁你必须要掌握的回调方法. spring bean在初始化和销毁的时候我们可以触发一些自定义的回调操作. 初始化的时候实现的方法 1.通过java提供的@Pos ...

  4. Spring单例Bean与单例模式的区别

    Spring单例Bean与单例模式的区别在于它们关联的环境不一样,单例模式是指在一个JVM进程中仅有一个实例,而Spring单例是指一个Spring Bean容器(ApplicationContext ...

  5. 责任链模式 多条链路时 spring单例 造成的深坑

    https://mp.weixin.qq.com/s/ipXPMtPawDdESMJYrYthcQ 一)线上事故: 催收系统每日自动分配案件时一直正常,突然某一天(2018-3-27)以后 案件分配不 ...

  6. 转载 spring单例bug

    https://www.cnblogs.com/fengzheng/p/14171443.html 这个 bug 让我更加理解 Spring 单例了 我是风筝,公众号「古时的风筝」,一个兼具深度与广度 ...

  7. spring 单例 获取多例的位_Spring系列第6篇:玩转bean scope,避免跳坑里!

    公众号关注"程序员二哥", 设为'星标',带你学习更多的知识. 本文内容 详细介绍5中bean的sope及使用注意点 自定义作用域的实现 应用中,有时候我们需要一个对象在整个应用中 ...

  8. spring 单例 获取多例的位_Spring 获取单例流程(一)

    读完这篇文章你将会收获到 在 getBean 方法中, Spring 处理别名以及 factoryBean 的 name Spring 如何从多级缓存中根据 beanName 获取 bean Spri ...

  9. java spring 单例_spring怎么实现单例模式?

    在Spring中,bean可以被定义为两种模式:prototype(多例)和singleton(单例) singleton(单例):只有一个共享的实例存在,所有对这个bean的请求都会返回这个唯一的实 ...

最新文章

  1. 高光荣教授逝世:他是新中国首位MIT计算机博士,开创数据流体系结构
  2. arguments don‘t support automatic differentiation, but one of the arguments
  3. LeetCode (2) - swift 实现数组 加一
  4. bash的环境配置文件
  5. 宇轩网络面试题目PHP,二十道接地气的php面试题,让你直接通过面试!就此奉上~...
  6. facebook快捷登录 pc_华为发布首款商用台式机,商用PC布局更进一步
  7. CSS border-style属性
  8. 2018.11.07-1015-幸运字符串查询 (lucky)
  9. HTML中常见的其它标签
  10. 走进缓存的世界(二) - 缓存设计
  11. 清华数据结构c语言版严蔚敏pdf,清华数据结构习题集答案(C语言版严蔚敏).pdf
  12. 信锐(SUNDRAY)无线控制器wifi无线上网短信认证设置流程
  13. linux把ftp挂载成盘符,使用curlftpfs将ftp空间挂载到本地
  14. win10网线插上显示的ipv6的服务器,win10如何开启IPV6及WIN10无法上ipv6的解决方法
  15. 一个呼叫中心系统应该怎样搭建?okcc呼叫系统
  16. 【扩张卷积or空洞卷积】如何理解Dilated Convolutions(空洞卷积)
  17. JS中children与childNodes的区别
  18. 上品携手SAP领跑服装零售行业
  19. [ CTF ] WriteUp- 2022年第三届“网鼎杯”网络安全大赛(玄武组)
  20. 影响网站收录的主要因素是什么?

热门文章

  1. antlr4 mysql_sharding-jdbc之ANTLR4 SQL解析
  2. 5.HTML图片的格式
  3. HDU1201(题解)18岁生日
  4. java char字节数_Java中char到底是多少字节?
  5. CSH 入门基础 2 -- csh(C Shell)对文件/目录的判断及对参数的处理
  6. GIS招聘 | 中国地质调查局14家各地单位招聘366人
  7. 李开复硅谷之行感悟:跟他们比,我们的创业者现在最缺什么?
  8. if语句matlab求被三整除的数,matlab能被3或4整除语句
  9. PHP数学运算函数大汇总
  10. 误删QQ空间里的照片可以恢复了?