3

AOP を使用するのはこれが初めてなので、これは非常に初歩的な質問かもしれません。

public class MyAspect implements AspectI {

public void method1() throws AsyncApiException {
    System.out.println("In Method1. calling method 2");
    method2();
}

@RetryOnInvalidSessionId
public void method2() throws AsyncApiException {
    System.out.println("In Method2, throwing exception");
    throw new AsyncApiException("method2", AsyncExceptionCode.InvalidSessionId);
}

public void login() {
    System.out.println("Logging");
}

InvalidSessionHandler は次のようになります。

@Aspect
public class InvalidSessionIdHandler implements Ordered {

    @Around("@annotation(com.pkg.RetryOnInvalidSessionId)")
    public void reLoginAll(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("Hijacked call: " + joinPoint.getSignature().getName() + " Proceeding");
        try {
            joinPoint.proceed();
        } catch (Throwable e) {
            if (e instanceof AsyncApiException) {
                AsyncApiException ae = (AsyncApiException) e;
                if (ae.getExceptionCode() == AsyncExceptionCode.InvalidSessionId) {
                    System.out.println("invalid session id. relogin");
                    AspectI myAspect = (AspectI) joinPoint.getTarget();
                    myAspect.login();
                    System.out.println("Login done. Proceeding again now");
                    joinPoint.proceed();
                }
            }
        }
    }

    @Override
    public int getOrder() {
        return 1;
    }
}

春の構成

<aop:aspectj-autoproxy />
<bean id="myAspect" class="com.pkg.MyAspect" />
<bean id="invalidSessionIdHandler" class="com.pkg.InvalidSessionIdHandler" />  
  1. 私の意図は、私が呼び出しmyAspect.method1()たとき、例外をスローしたmethod2場合にのみ再試行する必要があることです。しかし、上記のコードは何もしていないようです。method2 から例外がスローされた直後に戻ります。ただし、着ると全体が再試行されます。method2InvalidSessionIdmethod2@RetryOnInvalidSessionIdmethod1method1

  2. 私が保持した学習method2は公開されていますが、実際にはprivate. ここでは、プライベートメソッドを再試行する方法がわかりません。

どんな提案も役に立ちます。

ありがとう

4

1 に答える 1

5

これは、現在の設定では不可能です。Spring の AOP 機能を使用すると、クラスInvalidSessionIdHandlerは Bean として作成され、注釈/メソッド シグネチャなどをスキャンします。MyAspectあなたのクラスに関連しています。method2()すでに作成されている Bean をラップするプロキシを見つけて作成します。プロキシは、あなたのアドバイスから動作します。

Spring は、この (プロキシ) Bean を必要な場所に注入します。例えば:

public class MyClass {
   @Autowired
   private MyAspect aspect;

   public void callMethod2() {
       aspect.method2();
   }
}

この場合、MyClassオブジェクトにはプロキシへの参照があります。を呼び出すaspect.method2()と、追加された動作が実行されます。

ただし、コードでは、method2()内で呼び出すことを期待していますmethod1()

public void method1() throws AsyncApiException {
    System.out.println("In Method1. calling method 2");
    method2();
}

これはあなたのMyAspectクラス内にあります。技術的には、ここで起こっていることはas としてmethod2()呼び出されています。プロキシではなく、実際のオブジェクトへの参照です。したがって、追加の動作は実行されません。thisthis.method2()this

AOP Springのドキュメントでは、これについて詳しく説明しています。

ここでの回避策method2()は、別のクラス/オブジェクトになるようにリファクタリングするか、外部から呼び出すことです。からではありませんmethod1()

于 2013-07-31T19:46:38.880 に答える