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
018
019import io.jboot.Jboot;
020
021import java.util.Map;
022import java.util.concurrent.ConcurrentHashMap;
023
024public abstract class JbootrpcBase implements Jbootrpc {
025
026    protected static final Map<String, Object> serviceCache = new ConcurrentHashMap<>();
027    protected static JbootrpcConfig rpcConfig = Jboot.config(JbootrpcConfig.class);
028    private boolean started = false;
029
030
031    @Override
032    public <T> T serviceObtain(Class<T> interfaceClass, JbootrpcReferenceConfig config) {
033        String key = buildKey(interfaceClass, config);
034        T service = (T) serviceCache.get(key);
035        if (service == null) {
036            synchronized (this) {
037                service = (T) serviceCache.get(key);
038                if (service == null) {
039                    // onStart 方法是在 app 启动完成后,Jboot 主动去调用的
040                    // 但是,在某些场景可能存在没有等 app 启动完成就去获取 Service 的情况
041                    // 此时,需要主动先调用下 onStart 方法
042                    invokeOnStartIfNecessary();
043
044                    service = onServiceCreate(interfaceClass, config);
045                    if (service != null) {
046                        serviceCache.put(key, service);
047                    }
048                }
049            }
050        }
051        return service;
052    }
053
054    protected String buildKey(Class<?> interfaceClass, JbootrpcReferenceConfig config) {
055        return interfaceClass.getName() + "@" + config.hashCode();
056    }
057
058    protected synchronized void invokeOnStartIfNecessary() {
059        if (!started) {
060            onStart();
061            setStarted(true);
062        }
063    }
064
065
066    public abstract <T> T onServiceCreate(Class<T> serviceClass, JbootrpcReferenceConfig config);
067
068    @Override
069    public void onStart() {
070
071    }
072
073
074    @Override
075    public void onStop() {
076
077    }
078
079    public boolean isStarted() {
080        return started;
081    }
082
083    public void setStarted(boolean started) {
084        this.started = started;
085    }
086}