Spring注解【非单例】
花了至少一整天的时间解决了这个问题,必须记录这个纠结的过程,问题不可怕,思路很绕弯。
为了能说清楚自己的问题,我都用例子来模拟。
我有一个类MyThread是这样的:
- @Service
- public class MyThread extends Thread {
3 @Autowired
4 MyService myService;
5 ......
6 }
在主线程中有这样一个调用:
- @Autowired
- MyThread myThread;
- ......
- public void invoke{
- if(condition){
- myThread.start();
- }
- }
- ......
我的invoke存在一个循环调用,此时遇到了第一个问题!
问题一:抛出java.lang.IllegalThreadStateException。
问题一的解决:
- //@Autowired
- //MyThread myThread;
- ......
- public void invoke {
- if(condition){
6 //myThread.start();- MyThread myThread = new MyThread();
- myThread.start();
- }
- }
引发的新的问题!
问题二:我用了Spring注解,用new的话无法用注解实现注入,所以myThread中的myService对象抛出空指针。
问题二的解决:放弃了MyThread类,新写了一个类,开始绕弯。
- @Service
- public class MyRunable implements Runnable {
- @Autowired
- MyService myService;
- ......
- }
相应的,修改主线程中的调用。
- //@Autowired
- //MyThread myThread;
- @Autowired
- MyRunnable myRunnable;
- ......
- public void invoke{
- if(condition){
- //MyThread myThread = new MyThread();
- //myThread.start();
- Thread t = new Thread(myRunnable);
- t.start();
- }
- }
- ......
又遇到了新的问题!
我需要对myRunnable线程命名。即在invoke方法中增加这么一行:
- ......
- myRunnable.setName(name);//增加的一行
- Thread t = new Thread(myRunnable);
- ......
问题三:后面命名的myRunnable线程名称竟然覆盖前面的命名。
打印myRunnable对象,很容易判断出来这个对象是单例模式,所以每次改动都会影响以前的调用。
查了Spring的相关资料,得到结论,Spring默认管理类的模式就是“单例模式”,我需要改成非单例的。
尝试改动一:
- //增加了对象使用创建模式的注解
- @Service
- @Scope("prototype")
- public class MyRunable implements Runnable {
- @Autowired
- MyService myService;
- ......
- }
运行,问题依旧。然后就卡住了,甚至评估放弃Spring?一路new下去得了……
直到某一刻灵光闪现,发现虽然现在MyRunnble是非单例模式,但是在invoke的那个类中,Spring只在加载这个类时初始化了一个MyRunnable对象啊……
问题三的解决:
- //@Autowired
- //MyThread myThread;
- //@Autowired
- //MyRunnable myRunnable;
- ......
- public void invoke{
- if(condition){
- //MyThread myThread = new MyThread();
- //myThread.start();
- MyRunnable myRunnable = SpringContextUtil.getApplicationContext().getBean("myRunnable",MyRunnable.class);
- Thread t = new Thread(myRunnable);
- t.start();
- }
- }
- ......
这一步需要声明的是SpringContextUtil类有时间需要单独写一篇,先理解原理,就是每次从Spring容器中生成一个全新[scope("prototype")]的对象。
到这里,问题全部解决了……等等!
感觉MyThread类被抛弃好无辜啊!最终改成了这个样子的:
- MyThread myThread = SpringContextUtil.getApplicationContext().getBean("myThread", MyThread.class);
Spring注解【非单例】的更多相关文章
- atitit.guice3 绑定方式打总结生成非单例对象toInstance toProvider区别 v2 pb29
atitit.guice3 绑定方式打总结生成非单例对象toInstance toProvider区别 v2 pb29 1. 三 绑定方式的介绍1 2. To接口,链式绑定,用的最多的1 3. toC ...
- spring中如何向一个单例bean中注入非单例bean
看到这个题目相信很多小伙伴都是懵懵的,平时我们的做法大都是下面的操作 @Component public class People{ @Autowired private Man man; } 这里如 ...
- 【Java面试宝典】说说你对 Spring 的理解,非单例注入的原理?它的生命周期?循环注入的原理, aop 的实现原理,说说 aop 中的几个术语,它们是怎么相互工作的?
AOP与IOC的概念(即spring的核心) IOC:Spring是开源框架,使用框架可以使我们减少工作量,提高工作效率并且它是分层结构,即相对应的层处理对应的业务逻辑,减少代码的耦合度.而sprin ...
- 转:【Spring MVC Controller单例陷阱】
http://lavasoft.blog.51cto.com/62575/1394669/ Spring MVC Controller默认是单例的: 单例的原因有二:1.为了性能.2.不需要多例. 1 ...
- Spring MVC Controller单例陷阱
原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://lavasoft.blog.51cto.com/62575/1394669 Spr ...
- Spring bean 和单例bean的线程安全
Bean的作用域 Spring 3中为Bean定义了5中作用域,分别为singleton(单例).prototype(原型).request.session和global session,5种作用域说 ...
- Spring中的单例一二
Spring框架很好的帮助我们创建和管理dao.bean.service.action等对象, 但是它创建的对象是单例呢还是多例,又有哪些区别以及为什么 1.在Spring中默认创建的是单例模式,简单 ...
- spring如何解决单例循环依赖问题?
更多文章点击--spring源码分析系列 1.spring循环依赖场景2.循环依赖解决方式: 三级缓存 1.spring循环引用场景 循环依赖的产生可能有很多种情况,例如: A的构造方法中依赖了B的实 ...
- Spring对象类型——单例和多例
由于看淘淘商城的项目,涉及到了项目中处理spring中bean对象的两种类型,分别是单例和多例,就在此记录一下,方便加深理解,写出更加健壮的代码. 一.单例和多例的概述 在Spring中,bean可以 ...
随机推荐
- Sqlserver Sql Agent Job 只能同时有一个实例运行
Sqlserver Sql Agent中的Job默认情况下只能有一个实例在运行,也就是说假如你的Sql Agent里面有一个正在运行的Job叫"Test Job",如果你现在再去启 ...
- Unable to resolve target 'android-19'
修改两个地方,解决上面的问题
- Oracle 10g dataguard broker 配置
环境: OS:rhel6.3_64bit DB:Oracle10gR2 ————————————————————————dataguard broker配置—————————————————————— ...
- selenium webdriver设置超时
webdriver类中有三个和时间相关的方法: 1.pageLoadTimeout 2.setScriptTimeout 3.implicitlyWait pageLoadTimeout from s ...
- scala简单的文件操作
1.scala写入文件操作 package com.test import java.io.File import java.io.PrintWriter /** * scala文件写入 */ obj ...
- iOS 学习笔记 九 (2015.04.02)IOS8中使用UIAlertController创建警告窗口
1.IOS8中使用UIAlertController创建警告窗口 #pragma mark - 只能在IOS8中使用的,警告窗口- (void)showOkayCancelAlert{ NSSt ...
- Linux Kernel中断子系统来龙去脉浅析【转】
转自:http://blog.csdn.net/u011461299/article/details/9772215 版权声明:本文为博主原创文章,未经博主允许不得转载. 一般来说,在一个device ...
- textarea输入框限制字数(JS)
第一种: <textarea onkeyup="checkLen(this)"></textarea> <div>您还可以输入 <span ...
- 22、JSON/jQuery上
1)掌握JSON及其应用 2)了解jQuery的背景和特点 3)理解js对象和jQuery对象的区别 4)掌握jQuery九类选择器及应用(上) 声明:今天服务端我们使用Struts2技术 一 ...
- 关于sql server 2008过期导致 MSSQLSERVER服务就无法启动,手动启动就报告错误代码17051。
1.基本现象:MSSQLSERVER服务就无法启动,手动启动就报告17051错误. 2.解决办法: 第一步:进入SQL2008配置工具中的安装中心, 第二步:再进入维护界面,选择版本升级, 第三步:进 ...