9

spring-cloud-starter (つまり、すべてのマイクロサービス機能を備えた spring boot) を使用しています。javanica @HystrixCommand を使用してアノテーションが付けられたコンポーネントで hystrix メソッドを作成するときは、javanica github サイト ( https://github.com/Netflix/Hystrix/tree/master/hystrix-contrib/hystrix-javanica ) の指示に従って作成します。そのメソッドは、「Future<>」またはリアクティブ実行「Observable<>」のどちらを使用するかに関係なく、非同期で実行され、何も実行/実行されず
java.lang.ClassCastException: springbootdemo.EricComponent$1 cannot be cast to springbootdemo.Eric、結果を取得しようとするたびに取得します (Future<> の場合) または取得しますコールバック(リアクティブ実行の場合..およびprintlnのdontトリガーの場合、実際には実行されませんでした)。

public class Application { ...
}
@RestController
@RequestMapping(value = "/makebunchofcalls/{num}")
class EricController { ..

    @RequestMapping(method={RequestMethod.POST})
    ArrayList<Eric> doCalls(@PathVariable Integer num) throws IOException {
        ArrayList<Eric> ale = new ArrayList<Eric>(num);
        for (int i =0; i<num; i++) {
            rx.Observable<Eric> oe = this.ericComponent.doRestTemplateCallAsync(i);
            oe.subscribe(new Action1<Eric>() {
                @Override
                public void call(Eric e) {  // AT RUNTIME, ClassCastException
                    ale.add(e);
                }
            });
        }

        return ale;
    }

@Component
class EricComponent { ...

    // async version =========== using reactive execution via rx library from netflix ==============

    @HystrixCommand(fallbackMethod = "defaultRestTemplateCallAsync", commandKey = "dogeAsync")
    public rx.Observable<Eric> doRestTemplateCallAsync(int callNum) {
        return new ObservableResult<Eric>() {
            @Override
            public Eric invoke() {  // NEVER CALLED
                try {
                    ResponseEntity<String> result = restTemplate.getForEntity("http://doges/doges/24232/photos", String.class);  // actually make a call
                    System.out.println("*************** call successfull: " + new Integer(callNum).toString() + " *************");
                } catch (Exception ex) {
                    System.out.println("=============== call " + new Integer(callNum).toString() + " not successfull: " + ex.getMessage() + " =============");
                }
                return new Eric(new Integer(callNum).toString(), "ok");
            }
        };
    }

    public rx.Observable<Eric> defaultRestTemplateCallAsync(int callNum) {
        return new ObservableResult<Eric>() {
            @Override
            public Eric invoke() {
                System.out.println("!!!!!!!!!!!!! call bombed " + new Integer(callNum).toString() + "!!!!!!!!!!!!!");
                return new Eric(new Integer(callNum).toString(), "bomb");
            }
        };
    }
}

EricComponent$1ではなくが返されるのはなぜEricですか? ところで、Eric2つの文字列を持つ単純なクラスです...省略されています。

私は明示的に実行する必要があると考えていますが、それは次の理由で私をほのめかしています:私が得るそれを実行する方法。

4

1 に答える 1

6

アプリケーションクラスに@EnableHystrix注釈がありますか?

メソッドは非同期であり、subscribe同期コントローラー メソッドにリストを入力しようとしているため、問題がある可能性があります。を変更して、それが役立つかどうかを確認できsubscribeますtoBlockingObservable().forEach()か?

更新 #1 複製できました。デフォルトのメソッドは を返すのではなくObservable<Eric>、 だけを返す必要がありますEric

public Eric defaultRestTemplateCallAsync(final int callNum) {
    System.out.println("!!!!!!!!!!!!! call bombed " + new Integer(callNum) + "!!!!!!!!!!!!!");
    return new Eric(new Integer(callNum).toString(), "bomb");
}

更新 #2 ここで私のコードを参照してください https://github.com/spencergibb/communityanswers/tree/so26372319

更新 #3属性 をコメントアウトしたところ、AOPfallbackMethodのパブリック バージョンが見つからないという不平がありました。EricComponent私が作っEricComponent public staticて、それは働いた。独自のファイル内の最上位クラスは機能します。上記にリンクされている私のコードは機能し (restTemplate 呼び出しが機能すると仮定)、 を返しますn OK

于 2014-10-15T00:38:35.940 に答える