Java tutorial
/* * Copyright 2015 dactiv * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.github.dactiv.fear.service; import com.github.dactiv.fear.commons.ApiCaller; import com.github.dactiv.fear.commons.result.ApiResult; import com.github.dactiv.fear.commons.result.support.ErrorApiResult; import com.github.dactiv.fear.commons.result.support.SimpleApiResult; import com.google.common.collect.Maps; import org.apache.commons.lang3.ArrayUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.stereotype.Component; import org.springframework.util.ReflectionUtils; import java.lang.reflect.Method; import java.util.Date; import java.util.Map; /** * * RMI ? Api * * @author maurice */ @Component public class RemoteApiCaller implements ApiCaller { private final static Logger LOGGER = LoggerFactory.getLogger(RemoteApiCaller.class); @Autowired private ApplicationContext applicationContext; // ? private Map<String, Map<String, Method>> serviceCache = Maps.newConcurrentMap(); /** * ? * * @param serviceName ??? * @param methodName ?? * @param params ? * * @return */ @Override public ApiResult invoke(String serviceName, String methodName, Object... params) { SimpleApiResult simpleApiResult = new SimpleApiResult(new Date()); try { LOGGER.info("? " + serviceName + " ?"); Object bean = applicationContext.getBean(serviceName); Method method = getService(bean.getClass(), methodName, params); if (method == null) { method = findService(bean.getClass(), methodName, params); } // ?? if (method == null) { return new ErrorApiResult(simpleApiResult.getInvokeDate(), "?" + serviceName + "?" + methodName + "", ApiResult.NOT_FOUND, new Date()); } LOGGER.info(" " + serviceName + " ? " + method.getName() + " "); // Object data = ReflectionUtils.invokeMethod(method, bean, params); // ? null, ? json if (data != null) { simpleApiResult.setData(data); } // ? simpleApiResult.setCompleteDate(new Date()); LOGGER.info("? " + bean.getClass().getName() + "." + method.getName() + " "); return simpleApiResult; } catch (Exception e) { LOGGER.error(" api ", e); return new ErrorApiResult(simpleApiResult.getInvokeDate(), e, ApiResult.ERROR, new Date()); } } /** * ? * * @param targetClass class * @param method ?? * @param params ? * * @return */ public Method findService(Class<?> targetClass, String method, Object... params) { if (ArrayUtils.isNotEmpty(params)) { Class<?>[] paramTypes = convertParamToClass(params); return findParamMethod(targetClass, method, paramTypes); } else { return ReflectionUtils.findMethod(targetClass, method); } } /** * ?? * * @param targetClass class * @param method ?? * @param paramTypes ? * * @return */ private Method findParamMethod(Class<?> targetClass, String method, Class<?>[] paramTypes) { // ? Method[] methods = (targetClass.isInterface() ? targetClass.getMethods() : ReflectionUtils.getAllDeclaredMethods(targetClass)); // ? for (Method m : methods) { // ?? Class<?>[] methodParamTypes = m.getParameterTypes(); // ?????? if (m.getName().equals(method) && methodParamTypes.length == paramTypes.length) { // ?? Boolean flag = Boolean.TRUE; // ??flag true for (int i = 0; i < methodParamTypes.length; i++) { Class<?> paramTarget = paramTypes[i]; Class<?> paramSource = methodParamTypes[i]; if (paramTarget != null && paramTarget != paramSource && !paramSource.isAssignableFrom(paramTarget)) { flag = Boolean.FALSE; } } if (flag) { cacheService(targetClass, m, paramTypes); return m; } } } return null; } /** * ? * * @param targetClass class * @param method * @param paramTypes ??? */ private void cacheService(Class<?> targetClass, Method method, Class<?>[] paramTypes) { String targetName = targetClass.getName(); if (!serviceCache.containsKey(targetName)) { serviceCache.put(targetName, Maps.<String, Method>newLinkedHashMap()); } Map<String, Method> methodMap = serviceCache.get(targetName); String methodKey = getKey(method.getName(), paramTypes); if (!methodMap.containsKey(methodKey)) { methodMap.put(methodKey, method); } } /** * ?? * * @param targetClass class * @param methodName ?? * @param params ?? * * @return ?? */ private Method getService(Class<?> targetClass, String methodName, Object... params) { String targetName = targetClass.getName(); if (!serviceCache.containsKey(targetName)) { return null; } Class<?>[] paramTypes = convertParamToClass(params); String methodKey = getKey(methodName, paramTypes); Map<String, Method> methodMap = serviceCache.get(targetName); return methodMap.containsKey(methodKey) ? methodMap.get(methodKey) : null; } /** * ?? class * * @param params ? * * @return class */ private Class<?>[] convertParamToClass(Object... params) { Class<?>[] paramTypes = new Class<?>[params.length]; for (int i = 0; i < paramTypes.length; i++) { Object value = params[i]; if (value != null) { paramTypes[i] = params[i].getClass(); } else { paramTypes[i] = null; } } return paramTypes; } /** * ???? key * * @param methodName ?? * @param paramTypes ? * * @return key */ private String getKey(String methodName, Class<?>[] paramTypes) { StringBuilder builder = new StringBuilder("_"); for (Class<?> type : paramTypes) { if (type != null) { builder.append(type.getName()).append("_"); } } return methodName + builder.toString(); } }