001/**
002 * Copyright (c) 2015-2022, Michael Yang 杨福海 (fuhai999@gmail.com).
003 * <p>
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 * <p>
008 * http://www.apache.org/licenses/LICENSE-2.0
009 * <p>
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package io.jboot.components.rpc;
017
018import com.jfinal.aop.Aop;
019import io.jboot.Jboot;
020import io.jboot.components.event.JbootEventListener;
021import io.jboot.components.mq.JbootmqMessageListener;
022import io.jboot.components.rpc.annotation.RPCBean;
023import io.jboot.components.rpc.dubbo.JbootDubborpc;
024import io.jboot.components.rpc.local.JbootLocalrpc;
025import io.jboot.components.rpc.motan.JbootMotanrpc;
026import io.jboot.core.spi.JbootSpiLoader;
027import io.jboot.exception.JbootException;
028import io.jboot.exception.JbootRpcException;
029import io.jboot.utils.ArrayUtil;
030import io.jboot.utils.ClassScanner;
031import io.jboot.utils.ClassUtil;
032
033import java.io.Serializable;
034import java.util.List;
035
036
037public class JbootrpcManager {
038
039    private static JbootrpcManager manager = new JbootrpcManager();
040
041    public static JbootrpcManager me() {
042        return manager;
043    }
044
045    private Jbootrpc jbootrpc;
046    private JbootrpcConfig defaultConfig = Jboot.config(JbootrpcConfig.class);
047
048
049    public Jbootrpc getJbootrpc() {
050        if (jbootrpc == null) {
051            if (!defaultConfig.isConfigOk()) {
052                throw new JbootRpcException("Jboot RPC config is error, please set up \"jboot.rpc.type\" config value");
053            }
054            jbootrpc = createJbootrpc(defaultConfig);
055        }
056        return jbootrpc;
057    }
058
059
060
061    private static Class<?>[] default_excludes = new Class[]{
062            JbootEventListener.class,
063            JbootmqMessageListener.class,
064            Serializable.class
065    };
066
067
068    public void init() {
069
070        if (!defaultConfig.isConfigOk()) {
071            return;
072        }
073
074        Jbootrpc jbootrpc = getJbootrpc();
075        jbootrpc.onStart();
076
077        if (defaultConfig.isAutoExportEnable()) {
078            exportRPCBean(jbootrpc);
079        }
080    }
081
082    public void stop() {
083        if (defaultConfig.isConfigOk()) {
084            getJbootrpc().onStop();
085        }
086    }
087
088
089    public void exportRPCBean(Jbootrpc jbootrpc) {
090        List<Class> classes = ClassScanner.scanClassByAnnotation(RPCBean.class, true);
091        if (ArrayUtil.isNullOrEmpty(classes)) {
092            return;
093        }
094
095        for (Class<?> clazz : classes) {
096            RPCBean rpcBean = clazz.getAnnotation(RPCBean.class);
097            Class<?>[] inters = clazz.getInterfaces();
098            if (inters.length == 0) {
099                throw new JbootException("@RPCBean can not use for class \"" + ClassUtil.getUsefulClass(clazz).getName() + "\", because it has no interface.");
100            }
101
102            //对某些系统的类 进行排除,例如:Serializable 等
103            Class<?>[] excludes = ArrayUtil.concat(default_excludes, rpcBean.exclude());
104            for (Class<?> inter : inters) {
105                boolean isContinue = false;
106                for (Class<?> ex : excludes) {
107                    if (ex.isAssignableFrom(inter)) {
108                        isContinue = true;
109                        break;
110                    }
111                }
112
113                if (isContinue) {
114                    continue;
115                }
116
117                jbootrpc.serviceExport(inter, Aop.get(clazz), new JbootrpcServiceConfig(rpcBean));
118            }
119        }
120    }
121
122
123    public Jbootrpc createJbootrpc(JbootrpcConfig config) {
124        if(!config.isConfigOk()){
125            return null;
126        }
127
128        switch (config.getType()) {
129            case JbootrpcConfig.TYPE_DUBBO:
130                return new JbootDubborpc();
131            case JbootrpcConfig.TYPE_MOTAN:
132                return new JbootMotanrpc();
133            case JbootrpcConfig.TYPE_LOCAL:
134                return new JbootLocalrpc();
135            default:
136                return JbootSpiLoader.load(Jbootrpc.class, config.getType());
137        }
138    }
139
140
141}