1。インターセプターとフィルター
Spring Bootについて話す前に、まずフィルターとインターセプターを見てみましょう。 2つは機能の点で非常に似ていますが、特定の技術的実装にはまだ大きなギャップがあります。 2つの違いを分析する前に、まずAOPの概念を理解しましょう。 AOPは特定のテクノロジーではなく、プログラミングのアイデアです。オブジェクト指向プログラミングの過程で、継承と多型を通じて垂直拡大を解決することは簡単です。ただし、すべてのサービス方法でのトランザクションを有効にするなどの水平関数や、オブジェクト指向の関数を解決することはできません。したがって、AOP指向のプログラミングは、実際にはオブジェクト指向プログラミングのアイデアの補足です。今日私たちが話しているフィルターとインターセプターは、どちらもアスペクト指向プログラミングの特定の実装です。 2つの主な違いには、次の側面が含まれます。
1.フィルターはサーブレット容器に依存し、サーブレット仕様の一部です。インターセプターは独立して存在し、いかなる状況でも使用できます。
2。フィルターの実行は、サーブレットコンテナコールバックによって完了し、インターセプターは通常、動的プロキシを介して実行されます。
3.フィルターのライフサイクルはサーブレットコンテナによって管理され、インターセプターはIOC容器を介して管理できます。したがって、他の豆のインスタンスは注入やその他の方法で得ることができるため、使用する方が便利です。
2。フィルター構成
次に、フィルターを使用して、次のように実装されるリクエストの実行時間を記録する機能を実現します。
パブリッククラスのlogCostFilterを実装しているフィルター{@Override public void init(filterconfig filterconfig)servletexception {} @override public void dofilter(servletRequest servletResponse、servletResponse、filterchain filterchain)をスローfilterchain.dofilter(servletRequest、servletResponse); system.out.println( "cost ="+(system.currenttimemillis() - start)); } @Override public void Destroy(){}}このコードのロジックは比較的簡単です。これは、メソッドが実行される前にタイムスタンプを記録し、フィルターチェーンを介してリクエストの実行を完了し、返された結果間の実行時間を計算することです。ここでの主なことは、このクラスがフィルタークラスを継承しなければならないことです。これはサーブレットの仕様であり、以前のWebプロジェクトと違いはありません。ただし、フィルタークラスでは、以前のWebプロジェクトはWeb.xmlで構成できますが、Spring BootプロジェクトにはWeb.xmlファイルがありません。 Spring Bootでは、構成を完了するにはFilterRegistrationBeanが必要です。実装プロセスは次のとおりです。
@configurationPublic class filterconfig {@bean public filterregistrationbean registrationfilter(){filterregistrationbean登録= new FilterRegistrationBean();登録.setfilter(new logCostFilter());登録.addurlpatterns( "/*");登録.setName( "logCostFilter");登録.setorder(1);登録を返します。 }}この構成は完了します。構成する必要があるオプションには、主にフィルタークラスのインスタンス化、URLの一致するパターンを指定し、フィルター名と実行順序の設定が含まれます。このプロセスは、実際にはweb.xmlの構成と違いはありませんが、フォームはまったく異なります。これで、サーバーを起動して任意のURLにアクセスできます。
上記の構成が有効になっていることがわかります。 FilterRegistrationBeanを介して構成することに加えて、より直接的な方法もあります。これは、注釈を介して直接完了することができます。
@webfilter(urlpatterns = "/*"、filtername = "logfilter2")public class logcostfilter2を実装している{@Override public void init(filterconfig filterconfig)servletexception {} @Override public void dofilter(サーブレットサーブレクスレス、サーブレッツレクエスト) ioException、servletexception {long start = system.currenttimemillis(); filterchain.dofilter(servletRequest、servletResponse); system.out.println( "logfilter2 execute cost =" +(system.currenttimemillis() - start)); } @Override public void Destroy(){}}ここでは、@webfilterで直接構成できます。同様に、URLマッチングモード、フィルター名などを設定できます。ここで注意すべきことの1つは、注釈@WebFilterがサーブレット3.0の仕様であり、Spring Bootで提供されていないことです。この注釈に加えて、スキャンされたパッケージを指定して、構成クラス@servletcomponetscanに別の注釈を追加する必要があります。
@springbootapplication@mapperscan( "com.pandy.blog.dao")@servletcomponentscan( "com.pandy.blog.filters")public class application {public static void main(string [] args)throws {springapplication.run(application.rass、args); }}さて、もう一度URLにアクセスしましょう。
ご覧のとおり、構成した両方のフィルターが有効になっています。慎重な読者は、2番目のフィルターの実行順序を指定するのではなく、最初のフィルターの前に実行することがわかります。ここでは、@webfilterアノテーションが実行順序属性を指定していないことを説明する必要があります。その実行順序はフィルターの名前に依存し、フィルタークラス名のアルファベット順に基づいて逆順序で配置されます(構成されたフィルターの名前ではないことに注意してください)。 @WebFilterで指定されたフィルターの優先度は、FilterRegistrationBeanによって構成されたフィルターよりも高くなっています。興味のある友達は自分で実験できます。
3。インターセプター構成
上記のフィルター構成方法を既に導入しています。次に、インターセプターを構成する方法を見てみましょう。インターセプターを使用して上記の同じ関数を実装し、リクエストの実行時間を記録します。最初にインターセプタークラスを実装します。
パブリッククラスLogCostInterceptorは、HandlerInterceptor {long start = System.currentTimemillis(); @Override public boolean prehandle(httpservletrequest httpservletrequest、httpservletResponse httpservletResponse、object o)スロー例外{start = system.currenttimemillis(); trueを返します。 } @Override public void posthandle(httpservletrequest httpservletrequest、httpservletResponse httpservletResponse、object o、modelandview modelandview)system.out.println( "interceptor cost ="+(system.currenttimemillis()); } @Override public void aftercompletion(httpservletrequest httpservletrequest、httpservletResponse httpservletResponse、オブジェクトO、例外e)スロー例外{}}ここでは、HandlerInterceptorインターフェイスを実装する必要があります。このインターフェイスには3つの方法が含まれています。プレハンドはリクエストが実行される前に実行され、要求が実行された後にポスタンドラーは実行されますが、プリハンドルメソッドがtrueを返す場合にのみ実行されます。ビューレンダリングが完了した後、後部の整理が実行されます。 PrehandleはTrueを返す必要もあります。この方法は通常、リソースやその他のタスクのクリーニングに使用されます。上記のインターフェイスを実装することに加えて、以下を構成する必要があります。
@configurationPublic class InterceptorConfigはwebmvcconfigureradapter {@override public void addInterceptors(interceptorregistry registry){registry.addinterceptor(new logCostInterceptor())。 Super.AddDINTERCEPTORS(レジストリ); }}ここでは、webmvcconfigureradapterを継承しました。前の記事を読んだ友人は、このクラスを見たはずです。 Static Resource Directoryを構成するときに、このクラスを使用しました。ここでは、インターセプターを構成するためにAddInterceptorsメソッドを書き直しました。 2つの主要な構成項目があります。1つはインターセプターを指定することであり、もう1つはインターセプターURLを指定することです。次に、システムを開始し、任意のURLにアクセスします。
ご覧のとおり、インターセプターを通じて同じ機能を達成しました。ただし、PrehandleとPosthandleは2つの方法であるため、この実装には実際には問題があることに注意する必要があります。もちろん、この問題は、うまく解決できるThreadlocalなどの他の方法を介して解決できます。また、興味のある学生は自分で実装できます。ただし、これにより、多くのシナリオではインターセプターがフィルターよりも優れているが、このシナリオではフィルターがインターセプターよりも簡単に実装できることが実際にわかります。
4。概要
この記事では、主にスプリングブートに基づいたフィルターとインターセプターの構成について説明します。フィルターとインターセプターの両方が、AOP(断面指向のプログラミング)アイデアの特定の実装に属します。これらの2つの実装に加えて、別のより柔軟なAOP実装テクノロジー、つまり側面を見て、アスペクトを通じてますます強力な機能を完了することができます。これを後で共有します。