花了至少一整天的时间解决了这个问题,必须记录这个纠结的过程,问题不可怕,思路很绕弯。

为了能说清楚自己的问题,我都用例子来模拟。

我有一个类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注解【非单例】的更多相关文章

  1. atitit.guice3 绑定方式打总结生成非单例对象toInstance toProvider区别 v2 pb29

    atitit.guice3 绑定方式打总结生成非单例对象toInstance toProvider区别 v2 pb29 1. 三 绑定方式的介绍1 2. To接口,链式绑定,用的最多的1 3. toC ...

  2. spring中如何向一个单例bean中注入非单例bean

    看到这个题目相信很多小伙伴都是懵懵的,平时我们的做法大都是下面的操作 @Component public class People{ @Autowired private Man man; } 这里如 ...

  3. 【Java面试宝典】说说你对 Spring 的理解,非单例注入的原理?它的生命周期?循环注入的原理, aop 的实现原理,说说 aop 中的几个术语,它们是怎么相互工作的?

    AOP与IOC的概念(即spring的核心) IOC:Spring是开源框架,使用框架可以使我们减少工作量,提高工作效率并且它是分层结构,即相对应的层处理对应的业务逻辑,减少代码的耦合度.而sprin ...

  4. 转:【Spring MVC Controller单例陷阱】

    http://lavasoft.blog.51cto.com/62575/1394669/ Spring MVC Controller默认是单例的: 单例的原因有二:1.为了性能.2.不需要多例. 1 ...

  5. Spring MVC Controller单例陷阱

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://lavasoft.blog.51cto.com/62575/1394669 Spr ...

  6. Spring bean 和单例bean的线程安全

    Bean的作用域 Spring 3中为Bean定义了5中作用域,分别为singleton(单例).prototype(原型).request.session和global session,5种作用域说 ...

  7. Spring中的单例一二

    Spring框架很好的帮助我们创建和管理dao.bean.service.action等对象, 但是它创建的对象是单例呢还是多例,又有哪些区别以及为什么 1.在Spring中默认创建的是单例模式,简单 ...

  8. spring如何解决单例循环依赖问题?

    更多文章点击--spring源码分析系列 1.spring循环依赖场景2.循环依赖解决方式: 三级缓存 1.spring循环引用场景 循环依赖的产生可能有很多种情况,例如: A的构造方法中依赖了B的实 ...

  9. Spring对象类型——单例和多例

    由于看淘淘商城的项目,涉及到了项目中处理spring中bean对象的两种类型,分别是单例和多例,就在此记录一下,方便加深理解,写出更加健壮的代码. 一.单例和多例的概述 在Spring中,bean可以 ...

随机推荐

  1. Headless MSBuild Support for SSDT (*.sqlproj) Projects

    http://sqlproj.com/index.php/2012/03/headless-msbuild-support-for-ssdt-sqlproj-projects/ Update: bre ...

  2. sp_executesql的执行计划会被重用(转载)

    前一段时间,给一位朋友公司做咨询,看到他们的很多的存储过程都存在动态sql语句执行,sp_executesql,即使在没有动态表名,动态字段名的情况下仍然使用sp_executesql,这个做法是不太 ...

  3. 关于UIView(转)

    曾经有人这么说过,在iphone里你看到的,摸到的,都是UIView,所以UIView在iphone开发里具有非常重要的作用.那么UIView我们到底知道多少呢.请看看下面的问题, 如果这些你都知道, ...

  4. [转]编译Android源代码常见错误解决办法

    1. 编译时出现/usr/bin/ld: skipping incompatible /usr/lib/gcc/x86_64-linux-gnu/4.4.5/../../../libz.so when ...

  5. ch2-1:创建模块,并调用模块中的函数

    模块就是一个包含python代码的文本文件,文件名以.py结尾,这是python扩展名: 1.创建一个模块nester.py,文件内容为: '''这是一个模块,可以打印列表,其中可能包含嵌套列表''' ...

  6. 161123、ssh scp 复制文件和文件夹

    复制文件或目录命令:  复制文件:  (1)将本地文件拷贝到远程  scp 文件名用户名@计算机IP或者计算机名称:远程路径 本地192.168.80.100客户端  scp /root/instal ...

  7. 人工智能大数据,公开的海量数据集下载,ImageNet数据集下载,数据挖掘机器学习数据集下载

    人工智能大数据,公开的海量数据集下载,ImageNet数据集下载,数据挖掘机器学习数据集下载 ImageNet挑战赛中超越人类的计算机视觉系统微软亚洲研究院视觉计算组基于深度卷积神经网络(CNN)的计 ...

  8. JavaScript:九种弹出对话框

    [1.最基本的js弹出对话框窗口代码] 这是最基本的js弹出对话框,其实代码就几句非常简单: <script LANGUAGE="javascript"> <!- ...

  9. PHP安全函数phpinfo()

    phpinfo() 功能描述:输出 PHP 环境信息以及相关的模块.WEB 环境等信息. 危险等级:中 passthru() 功能描述:允许执行一个外部程序并回显输出,类似于 exec(). 危险等级 ...

  10. Entrust是一种为Laravel5添加基于角色的权限的简洁而灵活的方法。

    安装 首先要在composer.json中添加: "zizaco/entrust": "5.2.x-dev" 然后运行composer install 或者 c ...