问题描述

  在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注入的服务的解决办法的更多相关文章

  1. springboot中.yml没有spring的小叶子标志解决办法

    我的idea springboot项目中有两个.yml文件,一个application.yml,一个log4j2.yml,但是只有application.yml显示的是树叶图标,如下所示 做如下配置后 ...

  2. WCF服务运行一段时间后客户端无法连接WCF服务的解决办法 (转)

    WCF服务运行一段时间后客户端无法连接WCF服务的解决办法 (转) Windows Communication Foundation (WCF)是Microsoft为构建面向服务的应用提供的分布式通信 ...

  3. 5个Android开发中比较常见的内存泄漏问题及解决办法

    android中一个对象已经不需要了,但是其他对象还持有他的引用,导致他不能回收,导致这个对象暂存在内存中,这样内存泄漏就出现了.   内存泄漏出现多了,会是应用占用过多的没存,当占用的内存超过了系统 ...

  4. iOS9中关于 NSURLSession/NSURLConnection HTTP load failed 的解决办法

    最近为了新的存管app上线,忙了近一个月,重新过了一段996的日子,今天终于可以喘口气,继续更新博客了.本文记录一下在iOS 9中发送https请求遇到的问题及解决办法,希望通过本文,可以对ATS的配 ...

  5. 修改计算机名或IP后Oracle10g无法启动服务的解决办法

    修改计算机名或IP后Oracle10g无法启动服务的解决办法 遇到的问题,问题产生原因不详.症状为,windows服务中有一项oracle服务启动不了,报出如下错误. Windows 不能在 本地计算 ...

  6. ArcGIS客户端API中加载大量数据的几种解决办法

    ArcGIS客户端API中加载大量数据的几种解决办法 2011-03-25 18:17 REST风格的一切事物方兴未艾,ArcGIS Server的客户端API(Javascript/Flex/Sil ...

  7. jquery ajax success 函数 异步调用方法中不能给全局变量赋值的原因及解决办法

    jquery ajax success 函数 异步调用方法中不能给全局变量赋值的原因及解决办法   在调用一个jquery的ajax方法时我们有时会需要该方法返回一个值或者给某个全局变量赋值,可是我们 ...

  8. eclipse中运行出错:无法初始化主类的解决办法

    问题描述:eclipse中运行程序时,出现如下错误 解决办法: 出现此类:无法初始化主类有可能是因为eclipse中Java的版本与JDK的版本不匹配,我开始用的时候eclipse中用的是Java s ...

  9. 在Windows2008下安装SQL Server 2005无法启动服务的解决办法

    在Windows2012下安装SQL Server 2005无法启动服务的解决办法 1.正常安装任一版本的SQL Server 2005. 2.安装到SqlServer服务的时候提示启动服务失败  此 ...

随机推荐

  1. ASP.NET中的事件处理

    一.ASP.NET中的事件主要支持3个主要的事件组:1.包含在asp.net生成页面时自动生成,我们使用这些事件建立页面(如page_load等)2.包含了用户与页面交互时发生的所有事件(这种最强大) ...

  2. ubuntu学习之一

    1终端 在右键后菜单中找到 终端,(如果没有终端,使用 Ctrl+Alt+[F1~F6] ,您可以切换到1~6号控制台,输入: sudo apt-get install nautilus-open-t ...

  3. Sqli-labs less 36

    Less-36 我们直接看到36关的源代码 上面的check_quotes()函数是利用了mysql_real_escape_string()函数进行的过滤. mysql_real_escape_st ...

  4. 流程控制语句和增强for循环

    import java.lang.Math; //import java.util.Arrays; public class test{ public static void main(String[ ...

  5. c# 与flash通信简介

    许久不曾写随笔,即使许久的怠惰,是该抬抬头,看看天了. 公司项目,项目要求是在winForm端先获取下位机的肌电信号采集数据,然后根据这些数据的变化来控制flash游戏,这样一些患者在flash游戏中 ...

  6. POJ 2142 The Balance (解不定方程,找最小值)

    这题实际解不定方程:ax+by=c只不过题目要求我们解出的x和y 满足|x|+|y|最小,当|x|+|y|相同时,满足|ax|+|by|最小.首先用扩展欧几里德,很容易得出x和y的解.一开始不妨令a& ...

  7. Windows启动系统程序命令

    DEVMGMT.MSC - Device Manager 设备管理器 DISKMGMT.MSC - Disk Management 磁盘管理   WindowsXP常用命令http://baike.b ...

  8. UVA 11481 - Arrange the Numbers 数学

    Consider this sequence {1, 2, 3, . . . , N}, as a initial sequence of first N natural numbers. You ca ...

  9. linux系统中如何进入退出vim编辑器,方法及区别

    在linux家族中,vim编辑器是系统自带的文本编辑器,其功能强大自不必说了.偶有小白,刚接触linux,要修改某个文本文件,不可能像WINDOWS那样操作,更有甚者,进入VI编辑器后,无法退出以致强 ...

  10. Cloudinsight Agent install script

    #!/bin/bash # Cloudinsight Agent install script. set -e logfile="ci-agent-install.log" gis ...