2012-05-10 12 views
9

私はSpring 3 AOPを使用しています.HttpServletRequestへのアクセスが必要な側面があります。それはこのようなものになります。Autowired HTTPServletRequest beanのAOPおよびアスペクトスレッドの安全性を確保する

@Aspect 
public class MyAspect { 

    @Autowired 
    private HttpServletRequest httpServletRequest; 

    public void init() { 
     // Do something once... 
    } 

    @Before("my pointcut here...") 
    private void myMethod() { 
     // I need the httpServletRequest... 
    } 

    @After("my pointcut here...") 
    private void myOtherMethod() { 
     // I need the httpServletRequest... 
    } 
} 

をそして、このように構成されています

<bean id="myAspect" class="com.some.package.MyAspect" init-method="init" /> 

が、これは側面であっても、一度だけIoCコンテナあたりと呼ばれるinitメソッドで、安全HttpServletRequestのスレッドです?そうでない場合は、アドバイスの実行中にそれを取得してスレッドセーフにする最良の方法は何ですか?可能であれば、ローカルのスレッドを使用したくない場合があります。

答えて

16

それは、一度すべてのBeanインスタンスごとに呼び出されただけIoCコンテナ

ごとに一度と呼ばれるinitメソッドです。 Beanにシングルトンスコープがある場合(これはアスペクトのデフォルトの場合も同様です)、一度だけ呼び出されます。ただし、init()メソッド内のhttpServletRequestにアクセスすることはできません。リクエストはまだありません。

は、HttpServletRequestのスレッドセーフ

であることはありませんが、心配しないでください。これは実際には見た目よりはるかに複雑です。あなたは、HTTPサーブレットリクエスト(と同時にいくつかのリクエストを同時に利用できる)をシングルトンオブジェクトに注入しています。どちらが注射されるのですか?彼らの何も(すべて?)! Springはいくつかの高度なプロキシ(スコープ付きプロキシ)を作成し、注入されたメソッドhttpServletRequestにアクセスするたびに、それらを現在の(スレッドに)要求に委譲します。こうすることで、いくつかのスレッドでアスペクトを安全に実行できるようになります。各スレッドは、異なる物理的な要求に対して動作します。

この全体の動作は4.5.4.5 Scoped beans as dependenciesに大きな詳細に説明されています

[...]あなたはHTTPリクエストが別のBeanにBeanをスコープ(例えば)注入する場合、あなたは注射しなければなりませんスコープ付きBeanの代わりにAOPプロキシを使用します。つまり、スコープ付きオブジェクトと同じパブリックインターフェイスを公開するプロキシオブジェクトを挿入する必要がありますが、関連するスコープ(HTTP要求など)から実際のターゲットオブジェクトを取得し、メソッド呼び出しを実際のオブジェクトに委譲することもできます。

についてThreadLocal

私は地元のスレッドを使用しません。

幸いにも - 春はあなたのために1つを使用しています。 ThreadLocalがどのように動作するか理解していれば、Springは現在の要求をスレッドローカルに入れ、httpServletRequestプロキシにアクセスするとスレッドローカルインスタンスに委譲します。

+0

トム、これは素晴らしい答えです。 Springがこれをどこかに書いて、私が読めるようにすることは可能でしょうか?プロキシ処理が実際にどのように機能するかについては、何かを見つけるのは非常に困難でした。ああ、私はinit()内からのリクエストにアクセスする必要はありません - それは私を不正行為にして、2つの質問を1つに絞ることでした:) –

+0

@BrianReindel:私は私の答えにSpringのドキュメントへの参照を含めました。 –

+0

こんにちはトーマス、答えのコードは動作しますか?また、 "http://stackoverflow.com/questions/22923813/set-systems-property-in-controller-and-access-that-in-an-aspect"について意見を述べることはできますか? – riship89

関連する問題