springのbeanはマルチスレッドに注入する問題です。


問題の説明
springでは,非同期スレッドにビーンを注入する必要があると,ビーンが空であることが分かった。なぜなら、スプリング・バーはスレッドの安全を考慮して、ベアンからスレッド類に注入してはいけないからだそうです。コードは以下の通りです
public class DealThreadTask implements Runnable{



    @Autowired
    private DealService dealService;


    @Override
    public void run() {

    //  DealService dealService=holder.getBean("dealService");
        System.out.println("dealService-->"+dealService);
        dealService.deal("andy", "  ", 100d);


    }

}
controller層では、上記のserviceを呼び出します。

    public static void main(String[] args){

        ApplicationContext context=new ClassPathXmlApplicationContext("classpath:spring/applicationContext-aware.xml");
         DealThreadTask task=new DealThreadTask();
         new Thread(task).start();

    }
実行結果:
dealService-->null
Exception in thread "Thread-1" java.lang.NullPointerException
    at com.test.spring.tx.multi.DealThreadTask.run(DealThreadTask.java:38)
    at java.lang.Thread.run(Thread.java:744)
springはDealThreadTaskにdealServiceを注入できなかったと説明します。
解決方法
Spring APIにはApplication ContactixtAwareというインターフェースがあり、このインターフェースの種類を実現し、容器初期化完了中に容器を獲得することができ、容器中のすべてのbeanを獲得することができます。
public class ApplicationContextHolder implements ApplicationContextAware {

     private static ApplicationContext applicationContext;
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        ApplicationContextHolder.applicationContext=applicationContext;
        System.out.println("applicationContext---->"+applicationContext);
    }

     public static  T getBean(Class clazz){
         return applicationContext.getBean(clazz);
   }

     public static  T getBean(String name) {

         if (applicationContext==null) {
             System.out.println("applicationContext  ");
        }
            return (T) applicationContext.getBean(name);

     }
}
その後、xmlプロファイルには、このクラスを配置する必要があります。
<bean id="applicationContextHolder"  class="com.test.spring.tx.multi.ApplicationContextHolder">bean>
このように、非同期スレッド中のDealThreadTaskでは、マニュアルのappication Contactext HolderのgetBean方法により、必要なbeanを取得することができる。
public class DealThreadTask implements Runnable{



    @Autowired
    private ApplicationContextHolder holder;



    @Override
    public void run() {

        DealService dealService=holder.getBean("dealService");
        System.out.println("dealService-->"+dealService);
        dealService.deal("andy", "  ", 100d);


    }

}
ヒント
上記のコードには

    public static void main(String[] args){

        ApplicationContext context=new ClassPathXmlApplicationContext("classpath:spring/applicationContext-aware.xml");
         DealThreadTask task=new DealThreadTask();
         new Thread(task).start();

    }
junnitのtestコメントを使ってテストを行っていないのは、junnitが非同期スレッドの実行を待って終了するのではなく、junit自身の本スレッドのコードが実行されたら終了するからです。コードの中にデータベース操作が設計されていますので、簡単にjunnitでテストすれば、テストは完了しますが、データベース操作はまだ行われていません。junnitでテストをしたいなら、他の手段でthreadのjun操作やjunnitのテスト方法でキーボード入力を待って終わってもいいです。これらはすべて非同期スレッドを実行してからjunnitテストを終了するためです。