1. ホーム
  2. java

spring aop アドバイスからの Null 戻り値が、サマリーのプリミティブ戻り値と一致しない。

2022-02-08 22:04:56
<パス
  • アドバイスからのNull返り値が、プリミティブな返り値と一致しない。 これは通常、コードがラッピングを行った後に起こります。
  • ソースコードがこの例外を投げる場所を見つける(私は、使用しているcglibダイナミックプロキシのコードをグローバルに検索しました)CglibAopProxy#processReturnTypeです。
 private static Object processReturnType(Object proxy, Object target, Method method, Object retVal) {
		// Massage return value if necessary
		if (retVal ! = null && retVal == target && !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
			// Special case: it returned "this". Note that we can't help
			// if the target sets a reference to itself in another returned object.
			retVal = proxy;
		retVal = proxy; }
		Class<? > returnType = method.getReturnType();
		// isPrimitive This method is mainly used to determine if the Class is a primitive type (boolean, char, byte, short, int, long, float, double).   returnType ! = Void.TYPE whether it is a type without return value
		if (retVal == null && returnType ! = Void.TYPE && returnType.isPrimitive()) {
			throw new AopInvocationException(
					"Null return value from advice does not match primitive return type for: " + method);
		}
		return retVal;
	}



  • 例外の最初のケース。
    例えば、私のラップアラウンドコードは次のようなものです。
//Wrap around the methods in the service
  @Around("execute(* com.zzq.core.test.service. *. *(...)) ")
    public void around(ProceedingJoinPoint pjp ){
        System.out.println("AOP Aronud before... ");
       Object result = null;
         try {
            result = pjp.proceed();
            System.out.println("result : "+ result);
        } catch (Throwable e) {
            e.printStackTrace();
        }
        System.out.println("AOP Aronud after... ");
        }


サービスはこのようになります。

	@Override
	       public int select(int id) {
	            System.out.println("Enter DaoImpl.select() " + id);
	            return 1;
	  	   }


これは例外を投げます。

Exception in thread "main" org.springframework.aop.AopInvocationException: Null return value from advice does not match primitive return type for: public int com.zzq.core.test.service.impl.TestAopServiceImpl.select(int)
	at org.springframework.aop.framework.CglibAopProxy.processReturnType(CglibAopProxy.java:351)
	at org.springframework.aop.framework.CglibAopProxy.access$0(CglibAopProxy.java:341)
	at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:636)
	at com.zzq.core.test.service.impl.TestAopServiceImpl$$EnhancerBySpringCGLIB$$1f185468.select(<generated>)
	at com.zzq.core.test.BootStrap.main(BootStrap.java:18)


なぜなら loop does not return a value of null は、その select method return type is not void は、その but rather an int が、たまたま条件を満たしただけで、この例外を投げます。 int cannot match null ( unless it is a wrapper type Integer, but it always receives null ).
まだ、ラッパーを変更し、エラーを報告しないように戻り値を追加する必要があります。

  @Around("execute(* com.zzq.core.test.service. *. *(...)) ")
    public Object around(ProceedingJoinPoint pjp ){
        System.out.println("AOP Aronud before... ");
       Object result = null;
         try {
            result = pjp.proceed();
            System.out.println("result : "+ result);
        } catch (Throwable e) {
            e.printStackTrace();
        }
        System.out.println("AOP Aronud after... ");
        return result;
        }


  • エラー報告ケース II.
    上記のプラス戻り値やエラーと組み合わせて、それはプロキシメソッドエラー、上記のような選択メソッドエラーも報告される必要があります
    Null return value from advice does not match primitive return type for
    
    
    
    
    例えば、こんな感じ。
@Override
	       public int select(int id) {
	  			int a = 1 / 0;
	            System.out.println("Enter DaoImpl.select() " + id);
	            return 1;
	  	   }


プロキシメソッド select メソッドでエラーが報告され、プロキシメソッド try キャッチが実行されたはずです。 It's normal to not receive the return value of the proxy method after the error is reported, and null is returned, throwing an exception .

私はまだaopについてよく知らないので、この記事に間違いがあれば指摘してください、お願いします。