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"); 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM