1
zj
2025-06-23 dc9bd22833255bc602dd42c7f603ecb50842ab35
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
package kernel.rmi;
 
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
 
import org.springframework.context.ApplicationContext;
 
import kernel.web.ApplicationUtil;
 
/**
 * @author JORGE
 * @description RMI通用接口实现;
 * 本类在RMI架构中缺省为单例实现,即每一个应用类装载器对应一个RMI通用接口实例
 */
@SuppressWarnings({"serial","unused","unchecked"})
public class RmiFacadeImpl extends UnicastRemoteObject implements RmiFacade{
    /**
     * 常量提示(未实现远程接口)
     */
    private static final String NOT_IMPLEMENTED_INTERFACE="RMI-Server: %s : Not Implemented Remote Interface: %s";
    
    /**
     * 常量提示(未实现远程方法)
     */
    private static final String NOT_IMPLEMENTED_METHOD="RMI-Server: Remote Method Not Implemented For Interface: %s";
    
    /**
     * BeanMethod映射字典
     */
    private static final ConcurrentHashMap<String,BeanMethod> beanMethodMap = new ConcurrentHashMap<String,BeanMethod>();
    
    /**
     * @throws RemoteException
     */
    public RmiFacadeImpl() throws RemoteException {}
    
    /**
     * 通用远程接口实现
     * @param interfaceClass 远程接口类型
     * @param beanName BEAN名称
     * @param methodName 方法名
     * @param rmiEntity RMI实体
     * @return RMI实体
     */
    public RmiEntity invoke(String interfaceClass,String beanName,String methodName,RmiEntity rmiEntity) throws Exception {
        String cacheKey=null;
        Object[] methodArgs=rmiEntity.getParams();
        Class<?>[] paramTypes=rmiEntity.paramTypes;
        boolean emptyParams=(null==paramTypes || 0==paramTypes.length);
        String paramTypeStrs=emptyParams?"()":Arrays.stream(paramTypes).map(paramType->paramType.getName()).collect(Collectors.joining(",","(",")"));
        
        BeanMethod beanMethod=beanMethodMap.get(cacheKey=new StringBuilder(interfaceClass).append(".")
        .append(beanName).append(".").append(methodName).append(paramTypeStrs).toString());
        if(null!=beanMethod) return beanMethod.invoke(methodArgs);
        
        ApplicationContext appContext=ApplicationUtil.getApplicationContext();
        Class<?> intetrfaceType=appContext.getClass().getClassLoader().loadClass(interfaceClass);
        Map<String,Object> beanMap=(Map<String,Object>)appContext.getBeansOfType(intetrfaceType);
        
        if(null==beanMap || beanMap.isEmpty()) {
            throw new RuntimeException(String.format(Locale.ENGLISH,NOT_IMPLEMENTED_INTERFACE,ApplicationUtil.getContextPath(),interfaceClass));
        }
        
        Method targetMethod=emptyParams?findMethod(intetrfaceType,methodName):findMethod(intetrfaceType,methodName,paramTypes);
        
        if(null==targetMethod) {
            throw new RuntimeException(String.format(Locale.ENGLISH,NOT_IMPLEMENTED_METHOD,cacheKey));
        }
        
        Object beanImpl=beanMap.values().iterator().next();
        beanMethodMap.put(cacheKey,beanMethod=new BeanMethod(null==beanName?beanImpl:beanMap.getOrDefault(beanName,beanImpl),targetMethod));
        
        return beanMethod.invoke(methodArgs);
    }
    
    /**
     * 查找本地方法
     * @param beanClass BEAN类型
     * @param methodName 方法名
     * @return 本地方法对象
     */
    private static final Method findMethod(Class<?> beanClass,String methodName) {
        while (null!=beanClass) {
            Method[] targetMethods = beanClass.getDeclaredMethods();
            for (Method targetMethod : targetMethods) {
                int mod=targetMethod.getModifiers();
                if(!Modifier.isPublic(mod) || Modifier.isStatic(mod)) continue;
                if (!methodName.equals(targetMethod.getName())) continue;
                if(0!=targetMethod.getParameterCount()) continue;
                return targetMethod;
            }
            beanClass = beanClass.getSuperclass();
        }
        return null;
    }
    
    /**
     * 查找本地方法
     * @param beanClass BEAN类型
     * @param methodName 方法名
     * @param paramTypes 参数类型表
     * @return 本地方法对象
     */
    private static final Method findMethod(Class<?> beanClass,String methodName,Class<?>[] paramTypes) {
        while (null!=beanClass) {
            Method[] targetMethods = beanClass.getDeclaredMethods();
            out:for (Method targetMethod : targetMethods) {
                int mod=targetMethod.getModifiers();
                if(!Modifier.isPublic(mod) || Modifier.isStatic(mod)) continue;
                if (!methodName.equals(targetMethod.getName())) continue;
                if(0==targetMethod.getParameterCount()) continue;
                
                Class<?>[] targetMethodArgs=targetMethod.getParameterTypes();
                if(paramTypes.length!=targetMethodArgs.length) continue;
                
                for(int i=0;i<paramTypes.length;i++) {
                    if(ApplicationUtil.compatible(targetMethodArgs[i],paramTypes[i])) {
                        continue;
                    }else {
                        continue out;
                    }
                }
                
                return targetMethod;
            }
            beanClass = beanClass.getSuperclass();
        }
        return null;
    }
    
    /**
     * @author JORGE
     * @description BeanMethod
     */
    private static class BeanMethod{
        /**
         * BEAN实现
         */
        private Object targetBean;
        
        /**
         * 实现方法
         */
        private Method targetMethod;
        
        public BeanMethod(Object targetBean,Method targetMethod) {
            this.targetBean=targetBean;
            this.targetMethod=targetMethod;
        }
        
        public RmiEntity invoke(Object[] methodArgs) throws Exception {
            Object result=null;
            try {
                result=targetMethod.invoke(targetBean, methodArgs);
            }catch(InvocationTargetException e) {
                result=e.getCause();
                ((Throwable)result).printStackTrace();
            }catch(Throwable e) {
                result=e;
                e.printStackTrace();
            }
            
            return new RmiEntity(result);
        }
    }
}