线程中无法实例化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服务的时候提示启动服务失败 此 ...
随机推荐
- 疯狂java讲义——多态
父类 f = new 子类(); 引用变量f,在编译时类型是父类,在运行时类型是子类类型.当这个引用变量调用子类重写父类的那个方法的时候,实际执行的是子类中重写后的那个方法.当运行的时候调用该变量的方 ...
- jquery easyui tab加载内容的几种方法
转:http://my.oschina.net/u/2331760/blog/391937?fromerr=saqeoxxB jQuery Easyui 的tabs插件有两种方式加载某个tab(标签页 ...
- EditorWindow edit ScriptableObject
using UnityEngine; [System.Serializable] public class Weapon { //[SerializeField] public string weap ...
- Acdream1217 Cracking' RSA(高斯消元)
题意:给你m个数(m<=100),每个数的素因子仅来自于前t(t<=100)个素数,问这m个数的非空子集里,满足子集里的数的积为完全平方数的有多少个. 一开始就想进去里典型的dp世界观里, ...
- HDU 1397 Goldbach's Conjecture(二分,查找素数)
题目意思很简单,就是找n=p1+p2的种类数,具体看题目吧. 次重点是查找一定范围内的素数: 重点是用二分查找,不然会超时!!! #include<stdio.h> #include< ...
- HDU 2126 Buy the souvenirs (01背包,输出方案数)
题意:给出t组数据 每组数据给出n和m,n代表商品个数,m代表你所拥有的钱,然后给出n个商品的价值 问你所能买到的最大件数,和对应的方案数.思路: 如果将物品的价格看做容量,将它的件数1看做价值的话, ...
- ExtJs之Ext.util.TaskRunner
<!DOCTYPE html> <html> <head> <title>ExtJs</title> <meta http-equiv ...
- MFC中错误知识总结(一)
1.在继承与派生中,单目:表示派生,双目::表示继承,例如 class A { public: void c(); }; class B: public A {}; //类B继承类A void A:: ...
- Junit4中的新断言assertThat的使用方法
如果需要是用assertThat需要在项目中引入junit4的jar包.(匹配器和断言方法在junit4的jar包中都能找到,引入就可以了) 下面是常用断言的代码 1 import static or ...
- postgresql数据库的yum安装方法
实验环境>>>>>>>>>>>>>>>>>>操作系统:CentOS release 6.3 ...