6

Spring の自動配線とスコープに関するヘルプが必要です。

アプリの基本構造は次のとおりです。

  1. @Componentとして注釈が付けられたCustomHttpClientがあり、application.propertiesファイルから(@Value注釈を介して)いくつかの構成関連のプロパティもプルします。

  2. CustomHttpClient は、アプリケーションのいくつかのサービスで使用されています。CustomHttpClient を使用しているときはいつでも、次の方法でそのインスタンスを自動配線します。

    @Autowired
    private CustomHttpClient httpClient;
    
  3. 次のように、インターセプターを使用して CustomHttpClient 内の変数の一部を変更します。

    public class MyInterceptor extends HandlerInterceptorAdapter {
    @Autowired CustomHttpClient httpClient;
    
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    httpClient.setSomeProperty(newValue);
    ...
    

さて、ここで問題です。上記のようにすべてを設定した場合、VM が実行されている限り、インターセプターを介して CustomHttpClient の設定を変更するたびに、その新しい値が他のすべてのクライアントに対して保持されます。したがって、 httpClient.setSomeProperty() を実行すると、その設定が永久に保存されます。別のクライアントからアプリケーションに接続しても。

基本的に私が持っている必要があるのは2つのことです:

  1. CustomHttpClient のデフォルト設定をインターセプター (リクエストインターセプター、 経由で構成) を介してオーバーライドすることもできます。
  2. リクエストごとに CustomHttpClient の新しいインスタンスが作成されていることを確認してください (インターセプターがその魔法を実行した後)。

CustomHttpClient のスコープを @Scope("prototype") に変更してみましたが、それでは CustomHttpClient の設定をインターセプターで変更できなくなりました。

4

3 に答える 3

8

デフォルトでは、 @AutowiredSpring Bean スコープを使用する場合はシングルトンです。つまり、Spring は、使用する場所に同じシングルトン オブジェクトを注入します@Autowired。スコープprototypeを作成することで、Spring に @Autowired インジェクションごとに新しいオブジェクトを作成するように指示しているため、インターセプターには HttpClient の独自のコピーがあり、他の HttpClient オブジェクトを表示できません。

したがって、より良いアプローチは、シングルトン スコープを使用することです。リクエスト属性またはスレッドローカルを使用して、カスタム プロパティをリクエスト スレッドで実行します。つまり、インターセプターで HttpClient プロパティを変更する代わりに、いくつかのリクエスト属性またはスレッドローカルを設定し、これらのカスタム設定をCustomHttpClientクラス メソッド内で処理します。

于 2013-09-24T06:06:52.953 に答える
1

If your interceptor is only addding some properties then using thread local should be a better option. You can call ThreadLocal.set(custom Map) and use it wherever you want for the running thread and when your program is going to leave your controller you can call ThreadLocal.Unset which will clear the value stored.

This way you wont need a new instance of HttpcLient everytime, also a new instance every time would be a serious flaw. And you will be able to use your custom map anywhere you want in the running thread.

于 2013-09-24T04:53:10.620 に答える