@ SuppressWarnings ( "unchecked" ) public < T > T api ( Class < T > serviceInterface ) { final ServiceCall serviceCall = this ; final Map < Method , MethodInfo > genericReturnTypes = Reflect . methodsInfo ( serviceInterface ) ; // noinspection unchecked return ( T ) Proxy . newProxyInstance ( getClass ( ) . getClassLoader ( ) , new Class [ ] { serviceInterface } , ( proxy , method , params ) -> { final MethodInfo methodInfo = genericReturnTypes . get ( method ) ; final Class < ? > returnType = methodInfo . parameterizedReturnType ( ) ; final boolean isServiceMessage = methodInfo . isRequestTypeServiceMessage ( ) ; Optional < Object > check = toStringOrEqualsOrHashCode ( method . getName ( ) , serviceInterface , params ) ; if ( check . isPresent ( ) ) { return check . get ( ) ; // toString, hashCode was invoked. } switch ( methodInfo . communicationMode ( ) ) { case FIRE_AND_FORGET : return serviceCall . oneWay ( toServiceMessage ( methodInfo , params ) ) ; case REQUEST_RESPONSE : return serviceCall . requestOne ( toServiceMessage ( methodInfo , params ) , returnType ) . transform ( asMono ( isServiceMessage ) ) ; case REQUEST_STREAM : return serviceCall . requestMany ( toServiceMessage ( methodInfo , params ) , returnType ) . transform ( asFlux ( isServiceMessage ) ) ; case REQUEST_CHANNEL : // this is REQUEST_CHANNEL so it means params[0] must be a publisher - its safe to // cast. return serviceCall . requestBidirectional ( Flux . from ( ( Publisher ) params [ 0 ] ) . map ( data -> toServiceMessage ( methodInfo , data ) ) , returnType ) . transform ( asFlux ( isServiceMessage ) ) ; default : throw new IllegalArgumentException ( "Communication mode is not supported: " + method ) ; } } ) ; }
Create proxy creates a java generic proxy instance by a given service interface .