package com.dianping.pigeon.remoting.invoker.proxy; import com.dianping.pigeon.log.LoggerLoader; import com.dianping.pigeon.remoting.ServiceFactory; import com.dianping.pigeon.remoting.common.codec.SerializerFactory; import com.dianping.pigeon.remoting.common.exception.RpcException; import com.dianping.pigeon.remoting.common.util.Constants; import com.dianping.pigeon.remoting.invoker.ClientManager; import com.dianping.pigeon.remoting.invoker.InvokerBootStrap; import com.dianping.pigeon.remoting.invoker.config.InvokerConfig; import com.dianping.pigeon.remoting.invoker.exception.RouteException; import com.dianping.pigeon.remoting.invoker.route.balance.LoadBalanceManager; import com.dianping.pigeon.remoting.invoker.route.region.RegionPolicyManager; import com.google.common.collect.Interner; import com.google.common.collect.Interners; import org.apache.commons.lang.StringUtils; import com.dianping.pigeon.log.Logger; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; /** * Created by chenchongze on 15/12/17. */ public abstract class AbstractServiceProxy implements ServiceProxy { protected final static Map<InvokerConfig<?>, Object> services = new ConcurrentHashMap<InvokerConfig<?>, Object>(); protected Logger logger = LoggerLoader.getLogger(this.getClass()); private static final Interner<InvokerConfig<?>> interner = Interners.newWeakInterner(); private final RegionPolicyManager regionPolicyManager = RegionPolicyManager.INSTANCE; @Override public void init() { } @Override public <T> T getProxy(InvokerConfig<T> invokerConfig) { if (invokerConfig.getServiceInterface() == null) { throw new IllegalArgumentException("service interface is required"); } if (StringUtils.isBlank(invokerConfig.getUrl())) { invokerConfig.setUrl(ServiceFactory.getServiceUrl(invokerConfig)); } if (!StringUtils.isBlank(invokerConfig.getProtocol()) && !invokerConfig.getProtocol().equalsIgnoreCase(Constants.PROTOCOL_DEFAULT)) { String protocolPrefix = "@" + invokerConfig.getProtocol().toUpperCase() + "@"; if (!invokerConfig.getUrl().startsWith(protocolPrefix)) { invokerConfig.setUrl(protocolPrefix + invokerConfig.getUrl()); } } Object service = null; service = services.get(invokerConfig); if (service == null) { synchronized (interner.intern(invokerConfig)) { service = services.get(invokerConfig); if (service == null) { try { InvokerBootStrap.startup(); service = SerializerFactory.getSerializer(invokerConfig.getSerialize()).proxyRequest(invokerConfig); if (StringUtils.isNotBlank(invokerConfig.getLoadbalance())) { LoadBalanceManager.register(invokerConfig.getUrl(), invokerConfig.getSuffix(), invokerConfig.getLoadbalance()); } } catch (Throwable t) { throw new RpcException("error while trying to get service:" + invokerConfig, t); } // setup region policy for service try { regionPolicyManager.register(invokerConfig.getUrl(), invokerConfig.getSuffix(), invokerConfig.getRegionPolicy()); } catch (Throwable t) { throw new RouteException("error while setup region route policy: " + invokerConfig, t); } try { ClientManager.getInstance().registerClients(invokerConfig); } catch (Throwable t) { logger.warn("error while trying to setup service client:" + invokerConfig, t); } services.put(invokerConfig, service); } } } return (T) service; } @Override public Map<InvokerConfig<?>, Object> getAllServiceInvokers() { return services; } }