线程中无法实例化spring注入的服务的解决办法
问题描述
在Java Web应用中采用多线程处理数据,发现Spring注入的服务一直报NullPointerException。使用注解式的声明@Resource和XML配置的bean声明,都报空指针。然后寻找万能的网络寻找帮助,有的说spring因为考虑到线程安全问题,不支持注入,以及spring的bean声明周期,在工程启动时,没有检测到线程中的bean,进行注入。看来只能主动去获取spring声明的周期。
解决办法:
(1)主动实例化对象(不推荐)
private TestService testService = new TestServiceImpl();
每次加载这个类,就会重新创建一次,会过多耗费资源。
(2)把线程设置为主程序的内部类,或者是利用线程的构造方法把bean传递过去
主程序在web容器加载时,肯定是可以注入Spring bean的,那么将线程的实现类放在主程序的类中便可以“共享”Spring的bean,将生成线程的线程池定义在主程序的类中,每个线程的实现类作为内部类也定义在主程序中。
public class Test implements InitializingBean{
@Resource
private TestService testService
public void close(){
}
public void afterPropertiesSet() throws Exception {
// 利用构造方法把bean传递过去
new Thread(testService);
}
}
(3)用静态方法直接取的容器中的spring对象
写一个SpringContextUtil类,实现ApplicationContextAware
package com.test.utils; import java.util.Locale;
import java.util.Map; import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware; public class SpringContextUtil implements ApplicationContextAware { private static ApplicationContext applicationContext = null; public void setApplicationContext(ApplicationContext context) throws BeansException {
applicationContext = context;
} /**
* 获取applicationContext对象
* @return
*/
public static ApplicationContext getApplicationContext() {
return applicationContext;
} /**
* 根据bean的id来查找对象
* @param id
* @return
*/ public static <T> T getBeanById(String id) {
return (T) applicationContext.getBean(id);
} /**
* 根据bean的class来查找对象
* @param c
* @return
*/
public static <T> T getBeanByClass(Class c) {
return (T) applicationContext.getBean(c);
} /**
* 根据bean的class来查找所有的对象(包括子类)
* @param c
* @return
*/
public static Map getBeansByClass(Class c) {
return applicationContext.getBeansOfType(c);
} public static String getMessage(String key) {
return applicationContext.getMessage(key, null, Locale.getDefault());
} }
在applicationContext.xml中声明SpringContextUtil的bean
<bean id="springContextUtil" class="com.test.utils.SpringContextUtil"/>
在线程中或线程调用的其他服务中可以主动加载bean,然后可以直接使用(testService必须是spring中配置的bean)
public void run() {
TestService testService = (TestService ) SpringContextUtil.getBean("testService");
3 testService.queryData();
}
(4)看到网上说还可以通过BeanFactory来加载bean,没有去实现过,上个代码做个参考
public class SpringBeanFactoryUtils implements BeanFactoryAware {
private static BeanFactory beanFactory = null;
private static SpringBeanFactoryUtils factoryUtils = null;
6 public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
SpringBeanFactoryUtils.beanFactory = beanFactory;
}
public static BeanFactory getBeanFactory() {
return beanFactory;
}
public static SpringBeanFactoryUtils getInstance(){
if(factoryUtils==null){
//factoryUtils = (SpringBeanFactoryUtils)beanFactory.getBean("springBeanFactoryUtils");
factoryUtils = new SpringBeanFactoryUtils();
}
return factoryUtils;
}
public static Object getBean(String name){
return beanFactory.getBean(name);
}
}
线程中无法实例化spring注入的服务的解决办法的更多相关文章
- springboot中.yml没有spring的小叶子标志解决办法
我的idea springboot项目中有两个.yml文件,一个application.yml,一个log4j2.yml,但是只有application.yml显示的是树叶图标,如下所示 做如下配置后 ...
- WCF服务运行一段时间后客户端无法连接WCF服务的解决办法 (转)
WCF服务运行一段时间后客户端无法连接WCF服务的解决办法 (转) Windows Communication Foundation (WCF)是Microsoft为构建面向服务的应用提供的分布式通信 ...
- 5个Android开发中比较常见的内存泄漏问题及解决办法
android中一个对象已经不需要了,但是其他对象还持有他的引用,导致他不能回收,导致这个对象暂存在内存中,这样内存泄漏就出现了. 内存泄漏出现多了,会是应用占用过多的没存,当占用的内存超过了系统 ...
- iOS9中关于 NSURLSession/NSURLConnection HTTP load failed 的解决办法
最近为了新的存管app上线,忙了近一个月,重新过了一段996的日子,今天终于可以喘口气,继续更新博客了.本文记录一下在iOS 9中发送https请求遇到的问题及解决办法,希望通过本文,可以对ATS的配 ...
- 修改计算机名或IP后Oracle10g无法启动服务的解决办法
修改计算机名或IP后Oracle10g无法启动服务的解决办法 遇到的问题,问题产生原因不详.症状为,windows服务中有一项oracle服务启动不了,报出如下错误. Windows 不能在 本地计算 ...
- ArcGIS客户端API中加载大量数据的几种解决办法
ArcGIS客户端API中加载大量数据的几种解决办法 2011-03-25 18:17 REST风格的一切事物方兴未艾,ArcGIS Server的客户端API(Javascript/Flex/Sil ...
- jquery ajax success 函数 异步调用方法中不能给全局变量赋值的原因及解决办法
jquery ajax success 函数 异步调用方法中不能给全局变量赋值的原因及解决办法 在调用一个jquery的ajax方法时我们有时会需要该方法返回一个值或者给某个全局变量赋值,可是我们 ...
- eclipse中运行出错:无法初始化主类的解决办法
问题描述:eclipse中运行程序时,出现如下错误 解决办法: 出现此类:无法初始化主类有可能是因为eclipse中Java的版本与JDK的版本不匹配,我开始用的时候eclipse中用的是Java s ...
- 在Windows2008下安装SQL Server 2005无法启动服务的解决办法
在Windows2012下安装SQL Server 2005无法启动服务的解决办法 1.正常安装任一版本的SQL Server 2005. 2.安装到SqlServer服务的时候提示启动服务失败 此 ...
随机推荐
- 连接ACCESS 数据库不能使用 '';文件已在使用中。
错误类型: Microsoft JET Database Engine (0x80004005) 不能使用 '':文件已在使用中. 对数据库的操作完之后,要 conn.close() 错误原因:解 ...
- uiwebview和 js交互框架
WebViewJavascriptBridge
- BZOJ 1088
真是智商不够, 智商题:.... 假如:第1,2个格子已知,然后根据第二列的情况,就可以把所有满足的情况推出来,又萌萌哒.. 无耻攒字数: #include<stdio.h> using ...
- hadoop-ha QJM 架构部署
公司之前老的hadoop集群namenode有单点风险,最近学习此链接http://www.binospace.com/index.php /hdfs-ha-quorum-journal-manage ...
- ExtJS与jQuery的一点细节上的对比
首先说明这不是一篇完整解读ExtJS和jQuery所有方面差异的文章,只是针对我个人刚看了两天的jQuery产生的一些疑问的整理.之前用过一段时间ExtJS,了解ExtJS的一些机制.现在做移动开发, ...
- 在字符串S1中删除字符串S2中所包含的字符
/************************************************************************* > File Name: test.c &g ...
- Pytho中两种方式导入模块的差别
1.使用import module,只是把模块导入,访问模块中的函数名或者是属性是必须使用点运算符(.)来访问,否则直接访问会提示找不到这些函数或者属性. 2.使用from numpy import ...
- vim使用指北 ---- Advanced Editing
本节介绍vi和ex的一些高级功能. 配置vi 配置文件.exrc可以保存在你的主目录下,在vi启动的时候执行这个配置文件.但在当前工作目录下可以放置一个配置文件,对当前目录做一个自定义配置. :set ...
- hdu5017 Ellipsoid(旋转)
比赛的时候跳进这个大坑里,最后代码是写出来了.看到好像很多都是模拟退火做的,下面提供一个奇怪的思路吧. ax^2+by^2+cz^2+dyz+exz+fxy=1(*) 通过一些奇特的YY我们可以知道这 ...
- HDU 2672 god is a girl (字符串处理,找规律,简单)
题目 //1,1,2,3,5,8,13,21,34,55…… //斐波纳契数列 #include<math.h> #include<stdio.h> #include<s ...