Spring注解【非单例】
2016-03-10 14:54
197 查看
花了至少一整天的时间解决了这个问题,必须记录这个纠结的过程,问题不可怕,思路很绕弯。
为了能说清楚自己的问题,我都用例子来模拟。
我有一个类MyThread是这样的:
在主线程中有这样一个调用:
我的invoke存在一个循环调用,此时遇到了第一个问题!
问题一:抛出java.lang.IllegalThreadStateException。
问题一的解决:
引发的新的问题!
问题二:我用了Spring注解,用new的话无法用注解实现注入,所以myThread中的myService对象抛出空指针。
问题二的解决:放弃了MyThread类,新写了一个类,开始绕弯。
相应的,修改主线程中的调用。
又遇到了新的问题!
我需要对myRunnable线程命名。即在invoke方法中增加这么一行:
问题三:后面命名的myRunnable线程名称竟然覆盖前面的命名。
打印myRunnable对象,很容易判断出来这个对象是单例模式,所以每次改动都会影响以前的调用。
查了Spring的相关资料,得到结论,Spring默认管理类的模式就是“单例模式”,我需要改成非单例的。
尝试改动一:
运行,问题依旧。然后就卡住了,甚至评估放弃Spring?一路new下去得了……
直到某一刻灵光闪现,发现虽然现在MyRunnble是非单例模式,但是在invoke的那个类中,Spring只在加载这个类时初始化了一个MyRunnable对象啊……
问题三的解决:
这一步需要声明的是SpringContextUtil类有时间需要单独写一篇,先理解原理,就是每次从Spring容器中生成一个全新[scope("prototype")]的对象。
到这里,问题全部解决了……等等!
感觉MyThread类被抛弃好无辜啊!最终改成了这个样子的:
为了能说清楚自己的问题,我都用例子来模拟。
我有一个类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);
相关文章推荐
- JAVA 判断一个字符串是不是一个合法的日期格式
- (二) WebService-- JDK 发布WS服务
- (三) WebService-- JDK 客户端调用
- 毕业设计
- eclipse 调试之异常断点
- Java笔记
- 解决weblogic的JDK和编码问题
- Java 标准计算器(使用SWT做界面)
- java jersey介绍
- Java设计模式之装饰模式
- 基于java网上商城源码设计
- JDK JRE JVM
- Intellj IDEA14上用Debug启动项目启动不了:Unable to open debugger port: java.net.SocketException "socket closed"
- 通过Javacv摄像头连续抓图
- java连接mogodb
- Java是最基本的数据类型吗?
- Java Map遍历方式的选择
- struts2标签大全1
- 三张图彻底了解Java中字符串的不变性
- 【Eclipse】--jsp的默认打开为MyEclipse JSP Editor