Java(多)线程中注入Spring的Bean

问题说明 
今天在web应用中用到了Java多线程的技术来并发处理一些业务,但在执行时一直会报NullPointerException的错误,问题定位了一下发现是线程中的Spring bean没有被注入,bean对象的值为null。

原因分析 
web容器在启动应用时,并没有提前将线程中的bean注入(在线程启动前,web容易也是无法感知的)

解决方案 
方法有多种,网上也看到了不少。 
1. 使用static声明变量 
可参见

引用

http://blog.csdn.net/bjamosgavin/article/details/6125497

但这个方法自己试了一下但是没有成功。。。 
2. 把线程设置为主程序的内部类 
这也是一种简单的方法,主程序在web容器加载时肯定是可以注入Spring bean的,那么将线程的实现类放在主程序的类中便可以“共享”Spring的bean,(当然,这需要提前把线程中的需要用到的bean定义在外层的类中)。 
具体操作方法,就是将生成线程的线程池定义在主程序的类中,每个线程的实现类作为内部类也定义在主程序中。这个方法自己试过,是可以的。 
3. 使用静态方法直接取的容器中的spring对象 
这个方法稍微专业点,可以线程的分发与线程的实现分离出来。在每个线程中使用静态方法直接取的容器中的spring对象。 
使用静态方法获取容器中的spring对象可以参见

引用

http://littie1987.iteye.com/blog/937877, 
或者http://my.oschina.net/skyline520/blog/181158?p={{page}}

但一定要记住,你定义这个工具类也要配置成spring中的bean!

下面贴一下我在使用时的代码 
(1)定义工具类

public class SpringApplicationContextHolder implements ApplicationContextAware {  

    private static ApplicationContext context;  

    @Override
    public void setApplicationContext(ApplicationContext context) throws BeansException {
        SpringApplicationContextHolder.context = context;
    }  

    public static Object getSpringBean(String beanName) {
        notEmpty(beanName, "bean name is required");
        return context==null?null:context.getBean(beanName);
    }  

    public static String[] getBeanDefinitionNames() {
        return context.getBeanDefinitionNames();
    }  

在Spring中注册工具类的bean

<bean class="com.xxx.spring.SpringApplicationContextHolder" />  

线程中获取bean

UserRepo user = (UserRepo) SpringApplicationContextHolder.getSpringBean("userRepo"); 
时间: 2024-12-28 08:25:27

Java(多)线程中注入Spring的Bean的相关文章

java多线程中注入Spring对象问题

web应用中java多线程并发处理业务时,容易抛出NullPointerException. 原因: 线程中的Spring Bean没有被注入.web容器在启动时,没有提前将线程中的bean注入,在线程启动之前,web容器是无法感知的. 解决方案: 方法一.在声明成员变量的时候,将其定义为static的.(据说不可行) 方法二.将线程设置为主程序的内部类. 在外部类中注入bean,这样在内部类线程中就可以“共享”这个对象. 方法三.定义一个工具类,使用静态工厂方法通过getBean获得bean对

activiti中实现TaskListener注入Spring的bean

一开始我写的bpmn中 然后在我的监听器中注入的Spring的bean为空,注入不进来. 像这样,tenderService为null 注入不了. 此时需要把bpmn中这样设置,sendDocumentStartListener是监听器的类名(在这里首字母要小写) 监听器里要这么写(注意要加上@Component注解) 此时就可以注入Spring的bean了 原文地址:https://www.cnblogs.com/lqtbk/p/11018475.html

非spring组件servlet、filter、interceptor中注入spring bean

问题:在filter和interceptor中经常需要调用Spring的bean,filter也是配置在web.xml中的,请问一下这样调用的话,filter中调用Spring的某个bean,这个bean一定存在吗?现在总是担心filter调用bean的时候,bean还没被实例化? 答案:因为spring bean.filter.interceptor加载顺序与它们在 web.xml 文件中的先后顺序无关.即不会因为 filter 写在 listener 的前面而会先加载 filter.最终得出

Spring单例Bean中注入多例Bean

问题: 当在一个单例Bean中注入一个多例Bean的时候,是获取不到那个多例对象的,因为,单例在初始化的时候,就直接初始化,这个多例Bean啦, 一直获取的是第一次初始化的Bean 配置文件: <?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"    xmlns:xsi="htt

spring利用lookup-method标签单例bean中注入多例bean

1.单例bean A声明为抽象类,并编写抽象方法.如下: protected abstract B createB(); 2.在配置文件中配置如下: <bean id="a" class="A"> <lookup-method name="createB" bean="b"/> </bean> <bean id="b" class="B"/>

SpringMVC注入Spring的bean

一.Spring和SpringMVC两个IOC容器有什么关系呢? Spring的IOC容器包含了SpringMVC的IOC,即SpringMVC配置的bean可以调用Spring配置好的bean,反之则不可以 如果SpringMVC想通过@Autowired注入Spring容器里的属性,即使Spring配置文件已经配置好了 <context:component-scan base-package="com.wzy"></context:component-scan&g

Java子线程中的异常处理(通用)

在普通的单线程程序中,捕获异常只需要通过try ... catch ... finally ...代码块就可以了.那么,在并发情况下,比如在父线程中启动了子线程,如何在父线程中捕获来自子线程的异常,从而进行相应的处理呢? 常见错误 也许有人会觉得,很简单嘛,直接在父线程启动子线程的地方try ... catch一把就可以了,其实这是不对的. 原因分析 让我们回忆一下Runnable接口的run方法的完整签名,因为没有标识throws语句,所以方法是不会抛出checked异常的.至于Runtime

Java子线程中操作主线程Private级别数据

两个类分别如下: <pre name="code" class="java">package Demo2; import java.util.*; class Demo2 { private static ArrayList<String> a = new ArrayList<String>(); public static void main(String[] args) { a.add("String0")

【Java】线程中的wait和notify

线程中的同步问题通常使用的是synchronized块,结合wait和notify方法,今天简单做了一个测试.发现当一个线程锁定了某个临界资源后另一个线程会自动等待,以往自己还认为需要自己写代码让其等待呢... 共享资源: package sm.model; import org.apache.log4j.Logger; public class ThreadFuncs { /**  * Logger for this class  */ private static final Logger