AOP -- アノテーション @Aspect, @Pointcut
2022-03-02 03:10:03
内容
前に書く。開発プロセスでは、各メソッドの実行ログ、戻り値の解析、AOPに関する関連知識ポイントの簡単な整理が必要です。
1. 基本概念
1.1. タンジェントクラス @Aspect
Aspect、@Componentアノテーションを使用して、タンジェントクラスを定義します(下図)。
1.2. カットポイント @Pointcut
(1) カット方法の指定
<スパン 実行式
最初の * は、次のようなメソッドの戻り値にマッチすることを意味します。
<スパン ... (ドット2つ)は0個以上を意味し
は、モジュールパッケージとそのサブパッケージを示します。
2つ目の*は全クラスを示します。
3番目の*は、以下のすべてのメソッドを示します。
<スパン 2番目は... メソッドの任意の数のパラメータを示す
//org.jeecg.modules.dlglong.controller;
//com.sd3e.projectmanager.controller.acceptanceApplication;
@Pointcut("execute(public * org.jeecg.modules. *. *Controller.*(...)) ||execution(public * com.*.projectmanager... *. *Controller.*(...)) ")
public void excudeService() {
}
@Around("excudeService()")
public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
long time1 = System.currentTimeMillis();
Object result = pjp.proceed();
long time2 = System.currentTimeMillis();
log.debug("Get JSON data Time consumed: "+(time2-time1)+"ms");
long start=System.currentTimeMillis();
this.parseDictText(result);
long end=System.currentTimeMillis();
log.debug("Inject dictionary to JSON data Time consumed "+(end-start)+"ms");
return result;
}
@Pointcut("execute(public * com.rest.module. *. *(...)) ")
public void getMethods() {
}
@Pointcut("@annotation(org.jeecg.common.aspect.annotation.PermissionData)")
public void pointCut() {
}
package org.jeecg.common.aspect.annotation;
import java.lang.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation;
RetentionPolicy; import java.lang.annotation;
Target; import java.lang.annotation;
Target; /**
* Data permission annotation
* @Author taoyan
* @Date April 11, 2019
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE,ElementType.METHOD})
@Documented
public @interface PermissionData {
/**
* Not used for now
* @return
*/
String value() default "";
/**
* Configure the component path of the menu, used for data permissions
*/
String pageComponent() default "";
}
@Pointcut("@annotation(com.rest.utils.SysPlatLog)")
public void withAnnotationMethods() {
}
public @interface SysPlatLog {
// Operation name
String operateName() default "";
// operation description
String logNote() default "";
}
(2) アノテーションの指定
ここでは、カスタムアノテーションクラスを作成し、メソッドが動作するようにアノテーションしています。
@Before Execute before the cutpoint method
@After Executed after the cutpoint method
@AfterReturning Executed after the cutpoint method returns
@AfterThrowing Execute after a cutpoint method throws an exception
@Around is a wrap-around enhancement that controls the execution of the tangent before and after the execution of the tangent
//aop proxy object
Object aThis = joinPoint.getThis();
//proxied object
Object target = joinPoint.getTarget();
@AutoLog(value = "ws_xbx-paginated-list-query")
@ApiOperation(value="ws_xbx-paginated-list-query", notes="ws_xbx-paginated-list-query")
@GetMapping(value = "/list")
@PermissionData(pageComponent="sd3e/actDemo/WsXbxList")//sys_permission table component path component field
public Result<? > queryPageList(WsXbx wsXbx,
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
HttpServletRequest req) {
QueryWrapper<WsXbx> queryWrapper = QueryGenerator.initQueryWrapper(wsXbx, req.getParameterMap());
Page<WsXbx> page = new Page<WsXbx>(pageNo, pageSize);
IPage<WsXbx> pageList = wsXbxService.page(page, queryWrapper);
return Result.OK(pageList);
}
@SysPlatLog(operatorName = "View Details",logNote = "View Details")
@SneakyThrows
public Result getItem(@RequestParam(required = false) String bs){
}
package com.npc.rest.utils;
import com.npc.rest.common.properties.AppSupPlatProperties;
import com.sys.model.SysLog;
import lombok.extern.slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import java.lang.reflect;
import java.util.*;
@Aspect
@Slf4j
@Component
public class SysPlatLogAspect {
/**
* Specify the cut
*/
@Pointcut("execution(public * com.rest.module. *. *(...)) ")
public void getMethods() {
}
/**
* Specify the annotation
*/
@Pointcut("@annotation(com.rest.utils.SysPlatLog)")
public void withAnnotationMethods() {
}
/***
* Intercept the control layer operation log
* @param joinPoint
* @return
* @throws Throwable
*/
@After(value = "getMethods() && withAnnotationMethods()")
public void recordLog(JoinPoint joinPoint) throws Throwable {
SysLog sysLog = new SysLog();
SysPlatLog sysPlatLog = getInter(joinPoint);
sysLog.setOperateName(sysPlatLog.operateName());
sysLog.setLogNote(sysPlatLog.logNote());
sysLog.setLogTime(new Date());
sysLog.setAppCode(AppSupPlatProperties.getAppCode());
}
public SysPlatLog getInter(JoinPoint joinPoint) throws ClassNotFoundException {
String targetName = joinPoint.getTarget().getClass().getName();
String methodName = joinPoint.getSignature().getName();
String methodName = joinPoint.getSignature().getName(); Object[] arguments = joinPoint.getArgs();
Class targetClass = Class.forName(targetName);
Method[] methods = targetClass.getMethods();
for (Method method : methods) {
if (method.getName().equals(methodName)) {
Class[] clazzs = method.getParameterTypes();
if (clazzs.length == arguments.length) {
SysPlatLog sysPlatLog = method.getAnnotation(SysPlatLog.class);
return sysPlatLog;
}
}
}
return null;
}
}
1.3.アドバイス
エントリーポイントで行われるエンハンスメント処理で、主に5つの注釈がある。
@Before Execute before the cutpoint method
@After Executed after the cutpoint method
@AfterReturning Executed after the cutpoint method returns
@AfterThrowing Execute after a cutpoint method throws an exception
@Around is a wrap-around enhancement that controls the execution of the tangent before and after the execution of the tangent
1.4. ジョインポイント
メソッドで、パラメータ JoinPoint を結合点オブジェクトとして使用し、現在のカットインメソッドのパラメータやプロキシクラスなどを取得することで、何らかの情報を記録したり、何らかの情報を検証したりすることができるようになります。
1.5. 演算子の使用法
&&、 ||、 !を使用します。の有無の関係を表す接線表現を組み合わせるには、3つの演算子を使用します。
1.2. 例題はコードに記載
1.6. アノテーション(annotationType)
指定されたアノテーションがエントリポイントであるメソッドにマッチします。
1.7. プロキシオブジェクト
//aop proxy object
Object aThis = joinPoint.getThis();
//proxied object
Object target = joinPoint.getTarget();
1.8. タンジェントアノテーションの呼び出し
@AutoLog(value = "ws_xbx-paginated-list-query")
@ApiOperation(value="ws_xbx-paginated-list-query", notes="ws_xbx-paginated-list-query")
@GetMapping(value = "/list")
@PermissionData(pageComponent="sd3e/actDemo/WsXbxList")//sys_permission table component path component field
public Result<? > queryPageList(WsXbx wsXbx,
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
HttpServletRequest req) {
QueryWrapper<WsXbx> queryWrapper = QueryGenerator.initQueryWrapper(wsXbx, req.getParameterMap());
Page<WsXbx> page = new Page<WsXbx>(pageNo, pageSize);
IPage<WsXbx> pageList = wsXbxService.page(page, queryWrapper);
return Result.OK(pageList);
}
@SysPlatLog(operatorName = "View Details",logNote = "View Details")
@SneakyThrows
public Result getItem(@RequestParam(required = false) String bs){
}
2. コードの表示
package com.npc.rest.utils;
import com.npc.rest.common.properties.AppSupPlatProperties;
import com.sys.model.SysLog;
import lombok.extern.slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import java.lang.reflect;
import java.util.*;
@Aspect
@Slf4j
@Component
public class SysPlatLogAspect {
/**
* Specify the cut
*/
@Pointcut("execution(public * com.rest.module. *. *(...)) ")
public void getMethods() {
}
/**
* Specify the annotation
*/
@Pointcut("@annotation(com.rest.utils.SysPlatLog)")
public void withAnnotationMethods() {
}
/***
* Intercept the control layer operation log
* @param joinPoint
* @return
* @throws Throwable
*/
@After(value = "getMethods() && withAnnotationMethods()")
public void recordLog(JoinPoint joinPoint) throws Throwable {
SysLog sysLog = new SysLog();
SysPlatLog sysPlatLog = getInter(joinPoint);
sysLog.setOperateName(sysPlatLog.operateName());
sysLog.setLogNote(sysPlatLog.logNote());
sysLog.setLogTime(new Date());
sysLog.setAppCode(AppSupPlatProperties.getAppCode());
}
public SysPlatLog getInter(JoinPoint joinPoint) throws ClassNotFoundException {
String targetName = joinPoint.getTarget().getClass().getName();
String methodName = joinPoint.getSignature().getName();
String methodName = joinPoint.getSignature().getName(); Object[] arguments = joinPoint.getArgs();
Class targetClass = Class.forName(targetName);
Method[] methods = targetClass.getMethods();
for (Method method : methods) {
if (method.getName().equals(methodName)) {
Class[] clazzs = method.getParameterTypes();
if (clazzs.length == arguments.length) {
SysPlatLog sysPlatLog = method.getAnnotation(SysPlatLog.class);
return sysPlatLog;
}
}
}
return null;
}
}
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
ハートビート・エフェクトのためのHTML+CSS
-
HTML ホテル フォームによるフィルタリング
-
HTML+cssのボックスモデル例(円、半円など)「border-radius」使いやすい
-
HTMLテーブルのテーブル分割とマージ(colspan, rowspan)
-
ランダム・ネームドロッパーを実装するためのhtmlサンプルコード
-
Html階層型ボックスシャドウ効果サンプルコード
-
QQの一時的なダイアログボックスをポップアップし、友人を追加せずにオンラインで話す効果を達成する方法
-
sublime / vscodeショートカットHTMLコード生成の実装
-
HTMLページを縮小した後にスクロールバーを表示するサンプルコード
-
html のリストボックス、テキストフィールド、ファイルフィールドのコード例