博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring singleton bean 与 prototype bean 的依赖
阅读量:6277 次
发布时间:2019-06-22

本文共 2305 字,大约阅读时间需要 7 分钟。

本文同步至:

##问题

我们知道,Spring bean 默认的 scope 是 singleton(单例),但有些场景(比如多线程)需要每次调用都生成一个实例, 此时 scope 就应该设为 prototype。如:

<!-- more -->

@Component@Scope("prototype")public class DadTask implements Runnable {	static Logger logger = Logger.getLogger(DadTask.class);		@Autowired	DadDao dadDao;		private String name;	/**	 * 	 */	public DadTask setDadTask(String name) {		this.name = name;		return this;	}	/* (non-Javadoc)	 * @see java.lang.Runnable#run()	 */	@Override	public void run() {		logger.info("DadTask:"+this + ";DadDao:"+dadDao + ";"+dadDao.sayHello(name) );		//logger.info("Dad:"+name);	}}

但是,如果 singlton bean 依赖 prototype bean ,通过依赖注入方式, prototype bean 在 singlton bean 实例化时会创建一次(只一次), 比如:

@Servicepublic class UserService {	@Autowired	private DadTask dadTask;	public void startTask() {        ScheduledThreadPoolExecutor  scheduledThreadPoolExecutor  = new ScheduledThreadPoolExecutor(2);        scheduledThreadPoolExecutor.scheduleAtFixedRate(dadTask.setDadTask("Lily"), 1000, 2000, TimeUnit.MILLISECONDS);        scheduledThreadPoolExecutor.scheduleAtFixedRate(dadTask.setDadTask("Lucy"), 1000, 2000, TimeUnit.MILLISECONDS);	}}

我希望调度“Lily” 和 “Lucy” 两个线程,实际上,它只给我初始化一个实例(这样就线程非安全了)。

解决

如果 singlton bean 想每次都去创建一个新的 prototype bean 的实例, 需要通过方法注入的方式。 可以通过实现 ApplicationContextAware 接口,来获取到 ApplicationContext 实例, 继而通过 getBean 方法来获取到 prototype bean 的实例。我们的程序需要修改如下:

@Servicepublic class UserService implements ApplicationContextAware { 	@Autowired	private DadTask dadTask;		private ApplicationContext applicationContext; 	public void startTask() {        ScheduledThreadPoolExecutor  scheduledThreadPoolExecutor  = new ScheduledThreadPoolExecutor(2);                // 每次都拿到 DadTask 的实例        dadTask = applicationContext.getBean("dadTask", DadTask.class);        scheduledThreadPoolExecutor.scheduleAtFixedRate(dadTask.setDadTask("Lily"), 1000, 2000, TimeUnit.MILLISECONDS);        dadTask = applicationContext.getBean("dadTask", DadTask.class);        scheduledThreadPoolExecutor.scheduleAtFixedRate(dadTask.setDadTask("Lucy"), 1000, 2000, TimeUnit.MILLISECONDS);	}	@Override	public void setApplicationContext (ApplicationContext applicationContext) throws BeansException {        this.applicationContext = applicationContext;			}}

OK ,问题解决

源码

见 中 beanScope 目录

参考

转载于:https://my.oschina.net/waylau/blog/411926

你可能感兴趣的文章
jquery中hover()的用法。简单粗暴
查看>>
线程管理(六)等待线程的终结
查看>>
spring boot集成mongodb最简单版
查看>>
DELL EqualLogic PS存储数据恢复全过程整理
查看>>
《Node.js入门经典》一2.3 安装模块
查看>>
《Java 开发从入门到精通》—— 2.5 技术解惑
查看>>
Linux 性能诊断 perf使用指南
查看>>
实操分享:看看小白我如何第一次搭建阿里云windows服务器(Tomcat+Mysql)
查看>>
Sphinx 配置文件说明
查看>>
数据结构实践——顺序表应用
查看>>
python2.7 之centos7 安装 pip, Scrapy
查看>>
机智云开源框架初始化顺序
查看>>
Spark修炼之道(进阶篇)——Spark入门到精通:第五节 Spark编程模型(二)
查看>>
一线架构师实践指南:云时代下双活零切换的七大关键点
查看>>
ART世界探险(19) - 优化编译器的编译流程
查看>>
玩转Edas应用部署
查看>>
music-音符与常用记号
查看>>
sql操作命令
查看>>
zip 数据压缩
查看>>
Python爬虫学习系列教程
查看>>