Spring 多线程bean的问题(Spring+Javaweb中任务调度)

5 篇文章 0 订阅
4 篇文章 0 订阅

在写一个文件暂存系统的时候,有这样的一个需求:一个定时任务,每隔t分钟,做一些扫描操作。

实现思路是继承ContextLoaderListener,实现自己的Listener,在这个Listener中,开启定时任务。

一开始直接使用@Componet注解+@Autowired注解,结果导致注入失败。

由于一开始没意识到是线程的原因,所以在上网搜的原因及解决方案都是无效的,但也有一些有用的知识:

1.一般@Autowired注入失败有以下一个原因:

1.包没扫描到。

2.controller层的@controller或者service层的@Service注解没写

3.如果使用@Resource 注入service需要注意对象名字。

2.默认情况下,<context:component-scan>查找使用构造型(stereotype)注解所标注的类,如@Component(组件)@Service(服务),@Controller(控制器),@Repository(数据仓库)。

3.SpringSpringMVC整合的问题,二者在整合的时候,会产生两个容器,一个Spring容器,一个SpringMVC容器。Spring容器是父容器,SpringMVC容器是Spring容器的子容器。Spring容器初始化后,SpringMVC再进行初始化,并将Spring容器作为它的父容器。

子容器能够访问父容器的bean,而反之不行。

当父容器的初始化路径(base-package)等于或者包括了子容器的路径,那么可能出现,当SpringMVC子容器初始化时,如果发现有相同的类,会将新初始化的实例覆盖Spring容器中已经存在的实例,这可能导致注入失败,空指针的问题。

所以要做到2个容器要扫描的包必须相互区分,互不干扰。Spring容器扫描非Controller的实例,而SpringMVC容器扫描Controller的实例就行。

 

 

然后在一个论坛中得知了是线程的原因:

“因为主线程中可以直接使用@Autowired注解进行注入,但是在新开的线程中就不可以进行注入,每次启动服务器就会报空指针异常,新开启的线程直接就挂掉了,网上也搜了好多,原来是spring不会去管理这个新的线程,所以也就注入不进去任何bean。注解得方式最终都不能注入。

有以下几种方式来获取,我使用的是:通过工具类获取。Spring工具类获取bean

这种方法必须要把该工具类在SpringApplicationContext中注册bean,这样Spring才能通过工具类的set方法给其注入context。这样也带出了这种方法的弊端:工具类必须在Spring容器初始化完之后才能工作。

在现有的实现思路的基础上,这个弊端立刻就显现出来了,在自己重写的WebContextListener运行的时候,Spring容器是没有初始化的!所以会报空指针异常。

解决思路:工具类必须在Spring容器初始化完后才可以正常工作,那么可以找一个合适的位置开启(仅开启一次)任务调度器。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值