AOP@Before,@Aroundなどのメソッドの実行順序

38927 ワード

スプリングフレームワークで開発したことがある人は、多少AOP機能を使ったことがありますが、@Before、@Around、@Afterなどのadviceがあることは知っています.最近、プロジェクトの出力ログと権限制御の2つのニーズを実現するために、AOP機能も使用しました.@Before,@Aroundの2つのadviceを使用しました.しかし、使用中は実行順序が不明である.異なる状況で、これらのadviceがどのような順序で実行されているのかを明らかにするために、後で確認するためにテストを行いました.
前提条件
AOP関連クラス(aspect,pointcutなど)の概念については,本稿では説明しない.
springフレームワークをAOPにスキャンする方法についても説明しない.
ケース1:1つのメソッドは1つのAspectクラスによってのみブロックされる
1つのメソッドが1つのAspectによってのみブロックされる場合、このAspectの異なるadviceはどのような順序で実行されますか?以下を参照してください.
PointCutクラスの追加
このpointcutはtestパケットの下のすべてのクラスのすべてのメソッドをブロックするために使用されます.
package test;

import org.aspectj.lang.annotation.Pointcut;

public class PointCuts { @Pointcut(value = "within(test.*)") public void aopDemo() { } }

Aspectクラスの追加
このクラスのadviceでは、上記のpointcutが使用されます.使用方法は、各adviceのvalueプロパティを参照してください.
package test;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*; import org.springframework.stereotype.Component; @Component @Aspect public class Aspect1 { @Before(value = "test.PointCuts.aopDemo()") public void before(JoinPoint joinPoint) { System.out.println("[Aspect1] before advise"); } @Around(value = "test.PointCuts.aopDemo()") public void around(ProceedingJoinPoint pjp) throws Throwable{ System.out.println("[Aspect1] around advise 1"); pjp.proceed(); System.out.println("[Aspect1] around advise2"); } @AfterReturning(value = "test.PointCuts.aopDemo()") public void afterReturning(JoinPoint joinPoint) { System.out.println("[Aspect1] afterReturning advise"); } @AfterThrowing(value = "test.PointCuts.aopDemo()") public void afterThrowing(JoinPoint joinPoint) { System.out.println("[Aspect1] afterThrowing advise"); } @After(value = "test.PointCuts.aopDemo()") public void after(JoinPoint joinPoint) { System.out.println("[Aspect1] after advise"); } }

テスト用コントローラの追加
テスト用のコントロールを追加します.このコントロールには1つの方法しかありませんが、パラメータ値によって異なる処理が行われます.1つは正常にオブジェクトを返すことです.1つは異常を放出することです(@AfterThrowingというadviceをテストするためです).
package test;

import test.exception.TestException;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*; @RestController @RequestMapping(value = "/aop") public class AopTestController { @ResponseStatus(HttpStatus.OK) @RequestMapping(value = "/test", method = RequestMethod.GET) public Result test(@RequestParam boolean throwException) { // case 1 if (throwException) { System.out.println("throw an exception"); throw new TestException("mock a server exception"); } // case 2 System.out.println("test OK"); return new Result() {{ this.setId(111); this.setName("mock a Result"); }}; } public static class Result { private int id; private String name; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } } }

正常な状態のテスト
ブラウザに以下のURLを直接入力して、車に戻ります.
http://192.168.142.8:7070/aoptest/v1/aop/test?throwException=false

出力の結果は次のとおりです.
[Aspect1] around advise 1
[Aspect1] before advise test OK [Aspect1] around advise2 [Aspect1] after advise [Aspect1] afterReturning advise

テスト異常
ブラウザに以下のURLを直接入力し、車に戻ります.
http://192.168.142.8:7070/aoptest/v1/aop/test?throwException=true

出力の結果は次のとおりです.
[Aspect1] around advise 1
[Aspect1] before advise throw an exception [Aspect1] after advise [Aspect1] afterThrowing advise

結論