1. 周囲の注釈
アノテーションを囲む
サラウンド注釈 @Aroud
注釈 | 説明する |
---|---|
@その周り | @Around は Spring AOP の通知タイプであり、ターゲット メソッドの実行前後に周囲の操作を実行するために使用されます。メソッド呼び出しの前後に、ロギング、パフォーマンス監視などの追加のロジックを追加できます。@Around アノテーションを AspectJ 式と照合して、エントリ ポイントを指定し、アスペクト クラスのメソッドを定義し、メソッド内の ProceedingJoinPoint パラメータを通じてターゲット メソッドの実行プロセスを制御する必要があります。 |
サラウンド注釈により、拡張機能の統合が可能になります。
注釈を囲むには、ProceedingJoinPoint オブジェクトを作成し、対応する 2 つのメソッドを使用する必要があります。
方法 | 説明する |
---|---|
進む() | 通知された対象のメソッドを実行し、戻り値を返します。このメソッドは周囲のアドバイスで呼び出す必要があります。そうしないと、ターゲット メソッドは実行されません。 |
getArgs() | 対象メソッドのパラメータ値の配列を取得します。返されるパラメータ配列の型は Object です。 |
アノテーションを囲む使用例:
@Component
@Aspect
public class RoundAdvice {
@Around("com.alphamilk.Advice.MyPointcut.pointcut1()")
public Object Transation(ProceedingJoinPoint joinPoint){
// 获取方法参数
Object[] args = joinPoint.getArgs();
// 获取返回值
Object result = null;
try {
System.out.println("事务开始");
// 执行对应方法
result = joinPoint.proceed(args);
System.out.println("事务结束");
} catch (Throwable e) {
System.out.println("事务回滚");
throw new RuntimeException(e);
}
return result;
}
}
注: 拡張機能を使用するには、通知アノテーションを有効にする必要があります
@ComponentScan(value = "com.alphamilk")
@Configuration
//开启增强注解
@EnableAspectJAutoProxy
public class JavaConfig {
}
周囲のアノテーションを使用しない場合は、 @Before @After @AfterReturning などを使用する必要があります。
@Component
@Aspect
public class advice {
@Before("com.alphamilk.Advice.MyPointcut.pointcut1()")
public void Before(JoinPoint joinPoint) {
System.out.println("事务开始");
}
@After("com.alphamilk.Advice.MyPointcut.pointcut1()")
public void After(JoinPoint joinPoint) {
System.out.println("事务结束");
}
@AfterReturning(value = "com.alphamilk.Advice.MyPointcut.pointcut1()",returning = "result")
public void AfterReturning(JoinPoint joinPoint,Object result) {
System.out.println("调用拥有返回值的方法");
}
@AfterThrowing(value = "com.alphamilk.Advice.MyPointcut.pointcut1()",throwing = "throwable")
public void AfterThrowing(JoinPoint joinPoint,Throwable throwable) {
System.out.println("调用有异常的方法");
}
}
サラウンド注釈を使用する利点と欠点
アドバンテージ:
- 高い柔軟性: サラウンド アノテーションにより最大限の柔軟性が得られ、ターゲット メソッドの実行の前後に追加のロジック コードを挿入して、メソッドの実行プロセスを完全に制御できます。
- 統合された処理: 周囲のアノテーションを通じて、共通のロジック コードをアスペクトに抽出して、統合された処理ロジックを実現し、各ターゲット メソッドで同じコードを繰り返し記述することを回避できます。
- 戻り値は変更可能: 周囲のアドバイスでは、ターゲット メソッドの戻り値を変更することで最終結果が影響を受ける可能性があります。
欠点:
- 複雑さの増加: 他のタイプの通知と比較して、周囲の注釈の使用は若干複雑であり、特に ProceedingJoinPoint の使用については、より多くの理解と習熟が必要です。
- パフォーマンスのオーバーヘッド: 周囲のアノテーションがターゲット メソッド全体の実行プロセスをラップするため、場合によっては、特に処理ロジックがより複雑な場合、特定のパフォーマンスのオーバーヘッドが発生する可能性があります。
- 副作用の導入の可能性: サラウンド通知のターゲット メソッドに変更を加える場合は、プログラムの異常な動作や異常な動作につながる可能性のある、予期しない副作用の導入を避けるために注意して操作する必要があります。
2. 優先度のアノテーション
注釈 | 説明する |
---|---|
@注文 | @Order は、コンポーネントのロード順序を定義するために使用される Spring フレームワークのアノテーションです。クラスレベルまたはメソッドレベルで使用できます。複数のコンポーネントが同じインターフェイスを実装するか、同じ親クラスを継承する場合、 @Order アノテーションを使用してそれらの読み込み順序を指定できます。@Order の値が小さいほど優先度が高くなり、読み込み順序が高くなります。@Order アノテーションの値には任意の整数を指定できます。同じ優先度を持つコンポーネントのロード順序は不確実であるため、不確実性を避けるために優先度を異なる値に設定することをお勧めします。 |
同じメソッドに 2 つ以上の拡張機能があり、拡張の順序を指定する必要がある場合は、 @Order priority アノテーションを使用して設定する必要があります。
使用方法の核心は、優先順位を指定することです。Order の値が小さいほど、優先順位が高くなります。優先順位が高いほど、優先順位が高くなります。前が最初に実行され、最後が実行されます。
ケースコード: (最初の拡張)
@Component
@Aspect
//设置一个优先级更高注解
@Order(10)
public class advice {
@Before("com.alphamilk.Advice.MyPointcut.pointcut1()")
public void Before(JoinPoint joinPoint) {
System.out.println("优先级高前置执行");
}
@After("com.alphamilk.Advice.MyPointcut.pointcut1()")
public void After(JoinPoint joinPoint) {
System.out.println("优先级高后置后执行");
}
@AfterReturning(value = "com.alphamilk.Advice.MyPointcut.pointcut1()",returning = "result")
public void AfterReturning(JoinPoint joinPoint,Object result) {
System.out.println("调用拥有返回值的方法");
}
@AfterThrowing(value = "com.alphamilk.Advice.MyPointcut.pointcut1()",throwing = "throwable")
public void AfterThrowing(JoinPoint joinPoint,Throwable throwable) {
System.out.println("调用有异常的方法");
}
}
2つ目の強化
@Component
@Aspect
@Order(20)
public class RoundAdvice {
@Around("com.alphamilk.Advice.MyPointcut.pointcut1()")
public Object Transation(ProceedingJoinPoint joinPoint){
Object[] args = joinPoint.getArgs();
Object result = null;
try {
System.out.println("优先级低前置后执行");
// 执行对应方法
result = joinPoint.proceed(args);
System.out.println("优先级低后置先执行");
} catch (Throwable e) {
System.out.println("事务回滚");
throw new RuntimeException(e);
}
return result;
}
}