我々は、スプリングフレームを使用するプロセスでは、多くの場合、我々は、システムの効率を改善するための多くの方法の非同期実行を@async注釈を使用します。今日は、この機能を完了するために、どのように来春探ります。
走査方式スキャン上のスプリングBeanは注釈が@async、含まれている場合、ばねが動的に生成されたBeanのサブクラスになり、我々はプロキシクラスを呼び出す(?)含まれている場合、我々が書かれているプロキシクラスが継承されていますその後、豆、およびプロキシクラスに注入され、この時点で、このアプローチの実装では、この方法は非同期に実行すべきかどうかを判断するためにプロキシクラス、プロキシクラスになることを、彼らは我々が最初にBeanを書きました(親クラスを呼び出すことはありません、入って来ました)は、対応する方法。春には、このスレッドプールのキューを読み取るために待機して、キューに置かれ、キュー自身、彼が実行する必要があるような方法を維持し、実装プロセスを完了し、これ非同期関数を完了します。パラメータは、私たちは、スレッド・プールの数を設定することができますがあるとき私たちは、再設定の作業に集中することができます。この実装のので、@asyncコメントを追加すると呼ばれる同じクラスのメソッドは無効です!あなたが同じクラスにいるとき、メソッド呼び出しがクラス本体で実行されているので、春には、メソッドの呼び出しをインターセプトすることはできません。その一歩では、バネはAOP、アスペクト指向の機能を提供してくれます。彼の原理および非同期注釈の原理は、容器が定義されたクラス区分として走査されるばね開始類似しています。これらのクラスが注入されている場合は、あなたがこれらのメソッドを呼び出すときに、注入されたエージェントクラスは、プロキシクラスは、自然と呼ばれています。親クラスの実装方法は、AOPの実装を完了するためにコードの一部を実行する直前春対応するプロキシクラスを介して、コールの後どこへ行きますか! 我々は問題を持っていることを最後に、春は動的クラスのサブクラスを生成する方法ですか?演技のクラス?
簡単な紹介:
春はタスクのスケジューリングおよび非同期メソッドの実行は、アノテーションのサポートを提供しています。この方法で@Async注釈を提供することにより、このような方法は、非同期的に呼び出すことができます。あなたが呼ぶときに、発信者はすぐに戻りますが、メソッドの実際の実装が完了するまでに春のTaskExecutorと呼ばれるようになります。
オープン@Asyncノート:
<タスク:注釈駆動型のエグゼキュータ= "annotationExecutor" /> < -支持@Async注解- !> <タスク:エグゼキュータID = "annotationExecutor"プールサイズ= "20" />
スキャン注釈:<コンポーネントスキャン/コンテキスト>を追加しています。
栗:
比較のために、同期呼び出しに最初:
@Component パブリッククラスTestAsyncBean { 公共ボイドsayHello4()InterruptedExceptionある{スロー のThread.sleep(×1000 2); //ネットワーク接続。。。メッセージ送信。。。 System.out.println( "私は、ああ、あなたを愛して!"); }
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration({ "CLASSPATH:/applicationContext.xml"}) publicクラスTestAsync { @Test ます。public void test_sayHello4は()InterruptedExceptionある、ExecutionException {スロー するSystem.out.println(「あなたはまだ私を愛していないが? "); testAsyncBean.sayHello4(); System.out.printlnは("あなたは確かに私を愛していない、我々は戻ってとても遅い別れる...「); のThread.sleep * 1000(3); //早期メイン処理を終了しません } }
出力:
あなたは私を愛していないのですか? 私はあなたを愛して、ああ! 戻るので、遅い、あなたは確かに私を愛していない、私たちは別れます。。。
同期呼び出しは、コードシーケンスが続くが続き、そしてどこに待機する場合は、その後、継続しないダウンし、そこにブロックされます。
非同期の使用は@Asyncを呼び出します。
@Component パブリッククラスTestAsyncBean { @Async 公共ボイドsayHello3は()InterruptedExceptionある{スロー //ネットワーク接続、のThread.sleep(×1000 2)。。。メッセージ送信。。。 System.out.println( "私は、ああ、あなたを愛して!"); } }
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration({ "CLASSPATH:/applicationContext.xml"}) publicクラスTestAsync { @Autowired プライベートTestAsyncBean testAsyncBean; @Test 公共ボイドtest_sayHello3は()InterruptedExceptionある、ExecutionException {スロー 」するSystem.out.printlnを(あなたはもう私を愛していないのはなぜ");? testAsyncBean.sayHello3(); System.out.printlnは("あなたが実際に何も言うことはありません、私たちは別れる...「); のThread.sleep * 1000(3); //早期メイン処理を終了しません } }
出力:
あなたは私を愛していないのですか? あなたは実際に私たちは解散、何も言うことはありません。。。 私は、ああ、あなたを愛しています!
非同期呼び出し、新しいスレッドを開いて、呼び出し方法は、メインスレッドには影響しません。春のTaskExecutorへの非同期メソッドの実際の実行が完了します。
このように、上記の値を返す、次の非同期呼び出しをしようと、戻り値ではありません。
@Component パブリッククラスTestAsyncBean { @Async パブリックストリングsayHello2()InterruptedExceptionある{スロー のThread.sleep(×1000 2); //ネットワーク接続。。。メッセージ送信。。。 「私は、ああ、あなたを愛して!」を返す; //コールは、着信側の後すぐに戻り、そうはnullを返します } }
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration({ "CLASSPATH:/applicationContext.xml"}) publicクラスTestAsync { @Autowired プライベートTestAsyncBean testAsyncBean; @Test 公共ボイドtest_sayHello2は()InterruptedExceptionある、ExecutionException {スロー 」するSystem.out.printlnを(なぜあなたはもう私を愛していない");? のSystem.out.println(testAsyncBean.sayHello2()); System.out.printlnは("?あなたは)」...私たちが別れることを言う; のThread.sleep(3 * 1000); //途中メイン処理を終了しません } }
出力:
あなたはもう私を愛していないのはなぜ? ヌル あなたは私たちが別れる何?と言います。。。
リターンを介して直接アクセスは、それはあなたが非同期コールバックを使用する必要があり、ここで、動作しない価値がある、非同期メソッドは、値が呼び出し可能と未来として、今後の<>でなければなりません返します。
戻り値を取得するためにAsyncResult <>非同期呼び出しを次で:
@Component パブリッククラスTestAsyncBean { @Async 公共将来の<string> sayHello1()InterruptedExceptionある{スロー = 2 INT思考と、 のThread.sleep(思考* 1000); //ネットワーク接続。。。メッセージ送信。。。 System.out.println( "私は、ああ、あなたを愛して!"); 戻り新しい新しいAsyncResult <文字列>(+思考+ "秒" "とのメッセージを送ります"); } }
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration({ "CLASSPATH:/applicationContext.xml"}) publicクラスTestAsync { @Autowired プライベートTestAsyncBean testAsyncBean; @Test 公共ボイドtest_sayHello1は()InterruptedExceptionある、ExecutionException {スロー 将来の<string> = NULL未来; System.out.printlnは(「あなたはまだ私を愛していない?」); 未来= testAsyncBean.sayHello1(); System.out.printlnは(「あなたが実際に何も言うことはありません、私たちは別れる...」); スレッド.sleep(×1000 3); //一次処理が途中で終了させ するSystem.out.println(Future.get()); } }
出力:
あなたは私を愛していないのですか? あなたは実際に私たちは解散、何も言うことはありません。。。 私は、ああ、あなたを愛しています! 2秒でメッセージを送信します