コントローラ層の部分の構成を介してアクセスする統合ログインタフェースを達成するために
AOP
アスペクト指向プログラミングを、ダイナミックエージェントプログラムは、プリコンパイルと実行の仕方によって維持統一を達成するための技術を採用しています:AOPは意味、アスペクト指向プログラミングの略です。AOPは、開発の効率を向上させつつ、ビジネス・ロジックは、プログラムの再利用性を向上させ、部品間の結合度を低減するようなビジネス・ロジックの各部分を分離するために使用することができます。
AOP関連の用語
通知(アドバイス)
通知部は、やるべき仕事とする場合について説明しています。たとえば、私たちは各インターフェイスのログレコードの通話時間を削減する必要がある、あなたは、別途インターフェース呼び出しの前と後に現在の時刻を記録し、その後、差をとる必要があります。
- 事前通知(前):ターゲット・メソッド呼び出しの前に着信通知機能。
- (後)アドバイスを帰国後:コールの通知機能をターゲットメソッドの呼び出し後、メソッドの戻り結果を気にしません。
- リターン通知(AfterReturning):ターゲット・メソッドの後に呼び出し通知機能は正常です。
- 例外通知(AfterThrowing):ターゲットメソッドの後にコール通知機能は、例外をスローします。
- アドバイス(アラウンド)周り:通知対象のメソッド呼び出しカスタムの実行前と後の行動、客観的な方法を包みました。
接続点(ジョインポイント)
通知機能は、タイミングが適用されます。例えば、インタフェースメソッドが呼び出されたときには、接続点のログを切断することです。
タンジェントポイント(ポイントカット)
カット点の範囲通知機能が適用される定義します。このようなログは、すなわち、すべてのインタフェースコントローラ層法、すべてのインタフェースを切断されるようなアプリケーション。
セクション(アスペクト)
通知部は、いつ、どこで通知を適用するために定義するカット点の組み合わせです。
はじめに(はじめに)
変更することなく、既存のクラスの場合、または既存のクラス属性に新しいメソッドを追加します。
ウィービング(ウィービング)
ターゲットオブジェクトにカットし、新しいプロキシオブジェクトのプロセスを作成します。
春の注釈には、セクションを作成するために使用されます
関連の注意事項
- @Aspect:セクションを定義するために使用
- @Before:通知方法は、対象のメソッド呼び出しの前に実行されます
- @After:通知方法は、ターゲットメソッドが戻った後に実行するか、例外をスローします
- @AfterReturning:通知方法は、ターゲットメソッドの復帰後に実行されます
- @AfterThrowing:通知方法をターゲットメソッドの実行が例外をスローした後、
- @Around:通知方法は、ターゲットメソッドをカプセル化します
- @Pointcut:式はカットポイントを定義し
カットポイント式
指定通知の範囲は、表現形式を適用します:
execution(方法修饰符 返回类型 方法所属的包.类名.方法名称(方法参数)
1 // com.smartdata.pms.controllerパッケージパブリックメソッドは、通知部に適用されているすべてのクラス 2の実行(パブリック *のcom.smartdata.pms.controller。*。* (..)) 。3 // com.smartdataすべては、すべてのクラスメソッドで通知セクション.pms.serviceパッケージとそのサブパッケージに適用されます 。4実行(com.smartdata.pms .. * *。* (..)) 。5 // com.macro.mallを。全ての方法は、通知にtiny.service.PmsBrandServiceクラスセクションに印加される 。6が実行される(com.macro.mall.tiny.service.PmsBrandService *。*(..))
AOPセクションの実装にインタフェース・ロギングを追加します。
ログ情報パッケージタイプを追加するウェブログ
パッケージcom.smartdata.pms.log。 輸入lombok.Data; / ** * @ProjectName:smartdata * @Package:com.smartdata.pms.log * @ClassName:ウェブログ * @Author:heluwei * @description:コントローラベースのログ封入層 * @Date:2020年3月25日午前11時09分 * @Version:1.0 * / @データ パブリック クラスウェブログ{ / ** *操作説明 * / プライベート文字列の記述。 / ** *営業ユーザー * / プライベート文字列のユーザ名。 / ** *営業時間 * / プライベートロングたstartTime; / ** *時間がかかります * / プライベート整数spendTime。 / ** *ルートパス * / プライベート文字列basePathを。 / ** * URI * / プライベート文字列のURI。 / ** * URL * / プライベート文字列のURL。 / ** *要求タイプ * / プライベート文字列の方法。 / ** * IPアドレス * / プライベート文字列のIP; / ** *リクエストパラメータ * / プライベートオブジェクトのパラメータ。 / ** *リクエスト結果を返します * / プライベートオブジェクトの結果; }
カットクラスWebLogAspectを追加
セクションは、ログ、サラウンドで取得したログ情報は通知、コントローラ層を必要として行くためにすべてのパブリックメソッドに適用さを定義します。
パッケージcom.smartdata.pms.log。 輸入cn.hutool.core.util.StrUtil; 輸入cn.hutool.core.util.URLUtil; 輸入cn.hutool.json.JSONUtil; 輸入io.swagger.annotations.ApiOperation; 輸入lombok.extern.slf4j.Slf4j; 輸入org.aspectj.lang.JoinPoint; 輸入org.aspectj.lang.ProceedingJoinPoint; 輸入org.aspectj.lang.Signature。 輸入 org.aspectj.lang.annotation *。; 輸入org.aspectj.lang.reflect.MethodSignature。 輸入org.springframework.core.annotation.Order。 輸入org.springframework.stereotype.Component; インポートorg.springframework.util.StringUtils; 輸入org.springframework.web.bind.annotation.RequestBody。 輸入org.springframework.web.bind.annotation.RequestParam; 輸入org.springframework.web.context.request.RequestContextHolder。 輸入org.springframework.web.context.request.ServletRequestAttributes。 インポートのjavax.servlet.http.HttpServletRequest; 輸入java.lang.reflect.Methodオブジェクト; 輸入java.lang.reflect.Parameter; 輸入はjava.util.ArrayList; 輸入java.util.HashMapを; 輸入はjava.util.List; 輸入java.util.Map; / ** * @ProjectName:smartdata * @Package:com.smartdata.pms.log * @ClassName:WebLogAspect * @Author:heluwei * @description:統合ログ処理部 * @Aspect:セクションを定義するために使用されます * @Before:通知方法は、対象のメソッド呼び出しの前に実行されます * @After:通知方法は、ターゲットメソッド復帰後に実行するか、例外をスローします * @AfterReturning:通知方法は、ターゲット・メソッドの復帰後に実行されます * @AfterThrowing:通知方法は、ターゲットメソッドを実行した後に例外がスローされます * @Around:通知方法は、ターゲットメソッドをカプセル化します * @Pointcut:式定義されたカットポイント * @Date:2020年3月25日午前11時10分 * @Version:1.0 * / @Aspect // カット定義するために使用 @Component //はSpringコンテナに注ぎ @Orderを(1) // 小さな豆を実行する実行順序の春IOCコンテナプライオリティ値を定義 SLF4J @ パブリック クラスWebLogAspectを{ @Pointcut( "実行(公開* com.smartdata.pms.controller。*。*(..))" ) 公共 無効ウェブログ(){ } @Before( "ウェブログ()" ) 公共 ボイド doBefore(ジョインポイントジョインポイント)は、スローのThrowableを{ } (値@AfterReturning = "ウェブログ()" = "RET"を返す) 公共 ボイド doAfterReturning(オブジェクトRET)がスローされたThrowableを{ } @Around( "ウェブログ()" ) パブリックオブジェクトdoAround(ProceedingJoinPointジョインポイント)がスローされたThrowableを{ 長いのstartTime = のSystem.currentTimeMillis(); // 获取当前请求对象 ServletRequestAttributes属性= (ServletRequestAttributes)RequestContextHolder.getRequestAttributes(); リクエストしたHttpServletRequest = attributes.getRequest(); // レコードのリクエスト情報 ウェブログウェブログ= 新しい新しいウェブログ(); オブジェクトの結果 = joinPoint.proceed()。 署名署名 = joinPoint.getSignature()。 MethodSignature methodSignature = (MethodSignature)署名。 メソッドメソッドは、 = methodSignature.getMethodを(); もし(method.isAnnotationPresent(ApiOperation。クラス)){ ApiOperation apiOperation = method.getAnnotation(ApiOperation。クラス)。 webLog.setDescription(apiOperation.value())。 } 長い endTimeは= にSystem.currentTimeMillis(); ストリングurlStr = request.getRequestURL()のtoString()。 webLog.setBasePath(StrUtil.removeSuffix(urlStr、URLUtil.url(urlStr).getPath()))。 webLog.setIp(request.getRemoteUser())。 webLog.setMethod(request.getMethod())。 webLog.setParameter(のgetParameter(メソッド、joinPoint.getArgs()))。 webLog.setResult(結果)。 webLog.setSpendTime((int型)(endTimeは- のstartTime)); webLog.setStartTime(のstartTime)。 webLog.setUri(request.getRequestURI())。 webLog.setUrl(request.getRequestURL()のtoString())。 log.info( "{}" 、JSONUtil.parse(ウェブログ))。 戻り値の結果; } / ** *取得要求メソッドのパラメータと渡されたパラメータ * / プライベートオブジェクトのgetParameter(メソッドのメソッド、オブジェクト[]引数){ リストの<Object> argListに= 新のArrayList <> (); パラメータ[]パラメータ = method.getParameters(); のための(INT I = 0; I <parameters.length; I ++ ){ // requestBodyはリクエストパラメータとして注釈パラメータを変更し RequestBody requestBody =パラメーター[I] .getAnnotation (RequestBody。 クラス); IF!(requestBody = ヌル){ argList.add(引数[I])。 } // リクエストパラメータとして変性注釈RequestParamパラメータ RequestParam requestParam =パラメータ[I] .getAnnotation(RequestParam。クラス); IF(!= RequestParam NULL ){ 地図 <文字列、オブジェクト>マップ= 新しい HashMapの<> (); 文字列キー = パラメーター[I] .getName()。 もし(!StringUtils.isEmpty(requestParam.value())){ キー = requestParam.value()。 } map.put(キー、引数[I])。 argList.add(マップ) } } もし(argList.size()== 0 ){ 戻り ヌル。 } そう であれば(argList.size()== 1 ){ リターン argList.get(0 )。 } 他{ 戻りargListにします。 } } }