方法引用其实就是方法调用,符号是两个冒号::来表示,左边是对象或类,右边是方法。它其实就是lambda表达式的进一步简化。如果不使用lambda表达式,那么也就没必要用方法引用了。啥是lambda,参见jdk1.8新特性之lambda表达式。看实际例子:
先看函数式接口:
@FunctionalInterface public interface CompositeServiceMethodInvoker<M extends Message, R extends Message> { Logger LOGGER = LoggerFactory.getLogger(CompositeServiceMethodInvoker.class); ApiResult<M> invoke(InvokeContext ic, R r); default M getCompositeResponse(R request) throws PortalException { return getCompositeResponse(GetSpringContext.getInvokeContext(), request); } default M getCompositeResponse(InvokeContext invokeContext, R request) throws PortalException { if (LOGGER.isDebugEnabled()) { LOGGER.debug( "Enter CompositeServiceEngine.getCompositeResponse(), identityId:{}, requestClassName:{}, request:{}", CommonHttpUtil.getIdentity(), request.getClass().getName(), JsonFormatUtil.printToString(request)); } ApiResult<M> apiResult = invoke(invokeContext, request); if (Util.isEmpty(apiResult)) { LOGGER.error( " CompositeServiceEngine.getCompositeResponse(), Call microservice error, return null, identityId:{}," + " requestClassName:{}, request:{}", CommonHttpUtil.getIdentity(), request.getClass().getName(), JsonFormatUtil.printToString(request)); throw new PortalException(MSResultCode.MICROSERVICE_RETURN_NULL, (" CompositeServiceEngine.getCompositeResponse(), Call microservice error, return null, " + "requestClassName:") .concat(request.getClass().getName())); } int code = apiResult.getCode(); if (!apiResult.isSuccess()) { LOGGER.error( "Call CompositeServiceEngine.getCompositeResponse() error, identityId:{}, requestClassName:{}, " + "request:{}, return code:{}", CommonHttpUtil.getIdentity(), request.getClass().getName(), JsonFormatUtil.printToString(request), code); throw new PortalException(code, "Call CompositeServiceEngine.getCompositeResponse() error, requestClassName:".concat(request.getClass() .getName())); } else { M response = apiResult.getData(); if (Util.isEmpty(response)) { LOGGER.error( "Call CompositeServiceEngine.getCompositeResponse() error,return null, identityId:{}, " + "requestClassName:{}, request:{}, return code:{}", CommonHttpUtil.getIdentity(), request.getClass().getName(), JsonFormatUtil.printToString(request), code); throw new PortalException(code, "Call CompositeServiceEngine.getCompositeResponse() error, return null, requestClassName:".concat( request.getClass().getName())); } if (LOGGER.isDebugEnabled()) { LOGGER.debug( "Exit CompositeServiceEngine.getCompositeResponse(), identityId:{}, requestClasssName:{}, " + "request:{}, result:{}", CommonHttpUtil.getIdentity(), request.getClass().getName(), JsonFormatUtil.printToString(request), JsonFormatUtil.printToString(response)); } return response; } } default String getCompositeResponseCode(R request) throws PortalException { if (LOGGER.isDebugEnabled()) { LOGGER.debug( "Enter CompositeServiceEngine.getCompositeResponse() , identityId:{}, requestClassName:{}, request:{}", CommonHttpUtil.getIdentity(), request.getClass().getName(), JsonFormatUtil.printToString(request)); } ApiResult<M> apiResult = invoke(GetSpringContext.getInvokeContext(), request); if (Util.isEmpty(apiResult)) { LOGGER.error( " CompositeServiceEngine.getCompositeResponse(), Call microservice error, return null, " + "identityId:{}, requestClassName:{}, request:{}", CommonHttpUtil.getIdentity(), request.getClass().getName(), JsonFormatUtil.printToString(request)); throw new PortalException(MSResultCode.MICROSERVICE_RETURN_NULL, (" CompositeServiceEngine.getCompositeResponse(), Call microservice error, return null, " + "requestClassName:{}") .concat(request.getClass().getName())); } int code = apiResult.getCode(); if (LOGGER.isDebugEnabled()) { LOGGER.debug( "Exit CompositeServiceEngine.getCompositeResponse(), identityId:{}, requestClassName:{}, result:{}", CommonHttpUtil.getIdentity(), request.getClass().getName(), code); } return String.valueOf(code); } }
这里有3个默认方法,一个抽象方法,抽象方法返回对象ApiResult<M>。其中默认方法getCompositeResponse和getCompositeResponseCode调用了抽象方法invoke。再看返回该函数式接口实例的方法:
public class BookProductConsumer extends ServiceConsumer { public ApiResult<GetBookFeeDescResponse> getBookFeeDesc(InvokeContext context,
GetBookFeeDescRequest request) {
ServiceController controller = createRpcController("getBookFeeDesc",context);
ApiResult<GetBookFeeDescResponse> result = new ApiResult<GetBookFeeDescResponse>(controller);
stub.getBookFeeDesc(controller, request, result);
return result;
} }
这里的getBookFeeDesc方法返回了ApiResult对象(这里接口里的泛型M已经具体为GetBookFeeDescResponse对象了),如果我们使用lambda表达式,那么可以这么写:
CompositeServiceMethodInvoker<GetBookFeeDescResponse, GetBookFeeDescRequest> getBooFeeDescMethodInvoker = (InvokeContext context, GetBookFeeDescRequest request) -> { ServiceController controller = createRpcController("getBookFeeDesc", context); ApiResult<GetBookFeeDescResponse> result = new ApiResult<GetBookFeeDescResponse>(controller); stub.getBookFeeDesc(controller, request, result); return result; };
因为我们的变量getBooFeeDescMethodInvoker所指代的方法块已经定义在了BookProductConsumer类中,所以我们想直接使用BookProductConsumer的getBatchBookProductInfo方法:
CompositeServiceMethodInvoker<GetBookFeeDescResponse, GetBookFeeDescRequest> getBooFeeDescMethodInvoker = BookProductConsumer::getBookFeeDesc;
这就是类的方法引用,根据方法调用的不同情况,还有对象的方法引用、类的静态方法引用、类的构造方法引用。