线程中无法实例化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服务的时候提示启动服务失败 此 ...
随机推荐
- [工作积累] bitfield
ISO/IEC 14882:2003: 9.6 Bit-fields [class.bit] A member-declarator of the form identifieropt : const ...
- CSS3实现的渐变按钮,在IE7、IE6下的滤镜使用。
.ui-button { BORDER-LEFT-WIDTH:; ; COLOR: #fff; PADDING-BOTTOM: 0px; TEXT-ALIGN: center; PADDING-T ...
- 较复杂js的书写格式
我们看较复杂的js程序最怕结构混乱,一个好的js书写结构,在很大程度上可以减缓阅读的障碍性. 我感觉一个良好的结构要有两点:一是要有一个统一的入口,这样就保证了程序的可阅读性:二是要能够灵活的设置参数 ...
- 【转】CSS实现div的高度填满剩余空间
转自:http://www.cnblogs.com/zhujl/archive/2012/03/20/2408976.html 高度自适应问题,我很抵触用js去解决,因为不好维护,也不够自然,但是纯用 ...
- (转载)李剑英的CSLight入门指南结合NGUI热更新
原地址:http://www.xuanyusong.com/archives/3075 李剑英的CSLight入门指南文档撰写者:GraphicQQ: 1065147807 一. CSLIGHT 作者 ...
- MySQL注入load_file常用路径
WINDOWS下: c:/boot.ini //查看系统版本 c:/windows/php.ini //php配置信息 c:/windows/my.ini //MYSQL配置文件,记录管理员登陆过的M ...
- 使用 polyfills 的简易方法
本文作者为 Andrew Betts 与 Robert Nyman.Andrew 是金融时报(Financial Times)实验室主任,该实验室旨在金融时报开发并推广实践性的 Web 技术.Robe ...
- lintcode:二叉树的路径和
题目 给定一个二叉树,找出所有路径中各节点相加总和等于给定 目标值 的路径. 一个有效的路径,指的是从根节点到叶节点的路径. 解题 下面有个小bug 最后比较的时候是叶子节点为空,左右都有叶子结点,所 ...
- 545B. Equidistant String
题目链接 输入两个只含有01的字符串,s,t 求一个字符串p使到s,t的距离一样 这里的距离是指对应位置:0-0的距离是0 ,o-1的距离是1 ,1-1的距离是0,1-0的距离是1 这里只要求找出满足 ...
- java多线程理解2
1. 什么时候必须同步?什么叫同步?如何同步? 要跨线程维护正确的可见性,只要在几个线程之间共享非 final 变量,就必须使用 synchronized(或 volatile)以确保一个线程可以看见 ...