2013-04-18 5 views
13

Runnableを実装し、Springに送信されたTaskExecutorが自動的に呼び出されるクラスはありますか?Spring TaskExecutorに送信されたタスクの自動化

例えば、私はタスクを持っている:

public class MyTask implements Runnable { 

    @Autowired private MyRepository myRepository; 

    @Override 
    public void run() { 
     myRepository.doSomething(); 
    } 
} 

とスプリングのTaskExecutorにタスクを送信するサービス:

@Service 
public class MyService { 

    @Autowired private TaskExecutor taskExecutor; 

    public void someMethod() { 

     MyTask myTask = new MyTask(); 
     taskExecutor.execute(myTask); 

    } 

} 

私はMyTaskにはあるので、フィールドがautowiredされていない知っています新しいMyTask()を使用してインスタンス化されています。しかし、どうすればこれを回避できますか? SpringのApplicationContextにアクセスしてBeanを作成する必要がありますか?あなたはどのようにWebアプリケーション環境でこれを行いますか?

ありがとうございます!

答えて

4

としてMyServiceで変更することができます。まず、@Configurable注釈。これはAspectJへの依存を意味しますが、Springが管理していないBean(つまり、new演算子を使用している)を挿入することができます。これには、@ConfigurableでMyTaskに注釈を付けることと、リンクで言及されているようにSpring設定に2行追加することが含まれます。

@Configurable 
public class MyTask implements Runnable { ... } 

@Service 
public class MyService { 
    @Autowired private TaskExecutor taskExecutor; 

    public void someMethod() { 

    // AspectJ would jump in here and inject MyTask transparently 
    MyTask myTask = new MyTask(); 
    taskExecutor.execute(myTask); 

} 

}

第二のアプローチは、プロトタイプBeanを作成するために、春のServiceLocatorFactoryBean機能を使用して伴うだろう。う

@Service 
public class MyService { 
    @Autowired private TaskExecutor taskExecutor; 
    @Autowired private MyRepository myRepository; 
    @Autowired private TaskFactory taskFactory; 


public void someMethod() { 
    MyTask myTask = taskFactory.getTask("myTask") 
    taskExecutor.execute(myTask); 
} 

}

MyTaskに:これはJavaDocに最もよく説明するが、この状況で、あなたは、他のBeanのように、あなたの@Service注釈付きクラスにTaskFactoryを注入して、そのような何かをするだろうXMLマッピングでこれを設定できるので、すでにリポジトリを注入しておく必要があります。私は日常的にこれらのアプローチを両方使用していますが、私は読みやすいように第2のものを好む傾向があり、テスト可能ではないことを保証することによって開発者を正直に保つのに役立ちます。カジュアルな観察者には明らかです。

11

public class MyTask implements Runnable { 
    private MyRepository myRepository; 

    public MyTask(MyRepository myRepository) { 
     this.myRepository = myRepository; 
    } 

    @Override 
    public void run() { 
     myRepository.doSomething(); 
    } 
} 

@Service 
public class MyService { 
    @Autowired private TaskExecutor taskExecutor; 
    @Autowired private MyRepository myRepository; 


    public void someMethod() { 
     MyTask myTask = new MyTask(myRepository); 
     taskExecutor.execute(myTask); 
    } 
} 

を試すか、MyTaskにのスコープ=「プロトタイプ」を宣言し、春を使用して、これを行うには、少なくとも2つの良い方法があります

@Service 
public class MyService { 
    @Autowired private ApplicationContext ctx; 

    public void someMethod() { 
     MyTask myTask = ctx.getBean(MyTask.class); 
     taskExecutor.execute(myTask); 
    } 
} 
+0

はい、これは機能します。私はたくさんの依存関係を持っているので、Autowiringを作業に取り入れることを望んでいましたが、それらをすべて渡すことはしませんでしたが、その周りに道がないように見えます。 –

+1

別の方法があります。アップデートを参照してください。 –

+0

@EvgeniyDorofeev MyTaskをプロトタイプとしてどのように定義しましたか? – Dejell

関連する問題