web-dev-qa-db-ja.com

Spring BootでRequestContextListenerを構成する

Spring-Securityを使用するSpring-Bootアプリケーションがあります。セキュリティフィルターチェーン内のカスタムフィルターの1つに自動配線したい要求スコープBeanがありますが、現時点では機能していません。

DispatcherServletの外部で要求スコープのBeanを使用するにはいくつかの設定が必要であり、これを読んだことを理解しています http://docs.spring.io/spring/docs/4.0.x/spring-framework-reference/html /beans.html#beans-factory-scopes-other しかし、まだ成功していない:

Servlet 3.0+の場合、これはWebApplicationInitializerインターフェースを介してプログラムで実行できます。

(私は最新のTomcatを使用しているので、サーブレット3+です)

RequestContextListenerとRequestContextFilterの両方を使用してみました(ドキュメントによると、それらとDispatcherServletはまったく同じことをします)が、どちらの場合も、自動配線されたオブジェクトがnullであるため、エラーが発生します。

フィルターを登録する私の試み

_@Configuration
@ComponentScan
@EnableAutoConfiguration
class Application extends SpringBootServletInitializer  {

    @Override protected SpringApplicationBuilder configure( SpringApplicationBuilder application ) {
        application.sources( Application )
    }

    @Override public void onStartup( ServletContext servletContext ) throws ServletException {
        super.onStartup( servletContext )
        servletContext.addFilter("requestContextFilter", new RequestContextFilter() ).addMappingForUrlPatterns(null, false, "/*")
    }
_

リスナーを登録する私の試み

_@Configuration
@ComponentScan
@EnableAutoConfiguration
class Application extends SpringBootServletInitializer  {

    @Override protected SpringApplicationBuilder configure( SpringApplicationBuilder application ) {
        application.sources( Application )
    }

    @Override public void onStartup( ServletContext servletContext ) throws ServletException {
        super.onStartup( servletContext )
        servletContext.addListener( new RequestContextListener() ) 
    }
_

明らかな何かが欠けていますか?私はSpring Bootの自動設定ソースコードを見ましたが、まだ何も見つかりませんでした。


[〜#〜] update [〜#〜]

私はバカになっていたので、SpringSecurity構成のconfigure()メソッド内にフィルターを追加しました。

_http.addFilterBefore( new PreAuthFilter(), BasicAuthenticationFilter )
_

しかし、新しいフィルターをBeanとして登録していませんでした。以下のM. Deniumのコメントのとおり、リスナー/フィルターを明示的に追加する追加の構成はすべて必要ではなく、Beanを登録するだけで十分でした。

33
rhinds

更新/コメントで詳述されているように、これは私自身の愚かさによるものです。

Spring-Bootは、Request/SessionスコープBeanをDispatcherServletの外部にあるフィルターに自動接続できます。Springのドキュメントに従って、有効にするためにRequestContextListenerまたはRequestContextFilterを追加する必要があります。この機能:

要求、セッション、およびグローバルセッションレベル(WebスコープのBean)でBeanのスコープをサポートするには、Beanを定義する前にいくつかのマイナーな初期構成が必要です。 (この初期セットアップは、標準スコープ、シングルトン、およびプロトタイプには必要ありません。)...

実際に、Spring DispatcherServletまたはDispatcherPortletによって処理されるリクエスト内で、Spring Web MVC内のスコープBeanにアクセスする場合、特別な設定は必要ありません。DispatcherServletとDispatcherPortletはすべての関連する状態を既に公開します。

これを処理するには、RequestContextListener Beanを登録する必要がありました。

@Bean public RequestContextListener requestContextListener(){
    return new RequestContextListener();
} 

そのBeanを登録しないと、DispatcherServletの外部でRequestスコープにアクセスしようとしていることを示すエラーが表示されます。

私が経験した問題(自動配線されたオブジェクトはインジェクトされていない)は、SpringマネージドBeanではなく標準クラスインスタンスとしてカスタムフィルターを登録しているという事実が原因でした。

http.addFilterBefore( new PreAuthFilter(), BasicAuthenticationFilter )

これを解決するために、PreAuthFilterの作成を別の@Beanメソッドに移動したところ、@Autowired機能が正常に機能しました。

50
rhinds