web-dev-qa-db-ja.com

Spring @ Autowiredが新しいスレッドで機能しない

TaskJobを実行すると、SpringがserviceJobサービスを自動配線しないため、nullポインター例外が発生します。 SpringがmysqlServiceを問題なく自動配線したため、新しいスレッドがこの問題を引き起こしていますか?

public class TaskJob implements Runnable {
    @Autowired
    private ServiceJob serviceJob;

    String name;
    String source;

    public TaskJob(String name, String source) {
        this.name = name;
        this.source = source;
    }

    public void run() {
        serviceJob.run();
    }
}

@Service
public class ServiceJob extends BaseJob{

    @Autowired
    private MysqlService mysqlService;

    public void run(){
    ....
    }
}

@Service
public class MysqlService {
...
}

私のapplicationContext.xml;

<context:component-scan base-package="cm.*" /> 

そして私のクラスは;

cm.tasks.jobs.TaskJob
cm.jobs.ServiceJob
cm.services.MysqlService;

EDIT: TaskJobは;でインスタンス化されました

TaskJob taskJob = new TaskJob(name, source);
Thread taskThread = new Thread(taskJob);
taskThread.start();
10
hellzone

Springは、作成するコンポーネントのみを自動配線します。新しいTaskJob()を呼び出していますが、Springはこのオブジェクトを認識していないため、自動配線は行われません。

回避策として、アプリケーションコンテキストを直接呼び出すことができます。まず、アプリケーションコンテキストのハンドルを取得します。これは、アプリケーションコンテキスト自体に@Autowireを追加することで実行できます。

@Autowired
private ApplicationContext applicationContext;

TaskJobを作成するときは、アプリのコンテキストに自動配線を依頼してください。

TaskJob taskJob = new TaskJob(name, source);
applicationContext.getAutowireCapableBeanFactory().autowireBean(taskJob);

さらに、トリガーが必要な@PostConstructアノテーション付きメソッドがある場合は、initializeBean()を呼び出すことができます。

applicationContext.getAutowireCapableBeanFactory().initializeBean(taskJob, null);
16
Adam

TaskJobは、「new」演算子を使用してインスタンス化されます。これは、作成されたオブジェクトがSpringBeanではないことを意味します。そのため、new演算子を使用してプロパティ(ServiceJob)のオブジェクトを作成するコードを作成する必要があります。

Spring Spring Frameworkを使用している間、Serviceオブジェクトはこのように作成されません。 ApplicationcontextのgetBeanメソッドをご利用ください。ご覧ください こちら

2
subir