美文网首页
说一说OpenFeign中的一工厂方法实现

说一说OpenFeign中的一工厂方法实现

作者: 天草二十六_简村人 | 来源:发表于2021-04-27 15:46 被阅读0次

一、CachingSpringLoadBalancerFactory
从类的名字也可以看出来,它是一个具备缓存功能和生成LB的工厂方法。
除了构造函数,核心是create()方法了。
1、缓存是通过ConcurrentReferenceHashMap集合实现,Key值clientName(被调用方的服务名),如果找到了,则返回。

2、如果不存在,则调用组合类SpringClientFactory(也是一个工厂方法)的getClientConfig(clientName)和getLoadBalancer(clientName)「其实前两个方法也是由getInstance(String name, Class<C> type)实现」获取IClientConfig和ILoadBalancer。目的是创建FeignLoadBalancer的子类RetryableFeignLoadBalancer或者FeignLoadBalancer本身。

client = loadBalancedRetryFactory != null ? new RetryableFeignLoadBalancer(lb, config, serverIntrospector,
            loadBalancedRetryFactory) : new FeignLoadBalancer(lb, config, serverIntrospector);
// 其实下面三行代码的本质都是从应用上下文获取相应的对象。
IClientConfig config = this.factory.getClientConfig(clientName);
        ILoadBalancer lb = this.factory.getLoadBalancer(clientName);
        ServerIntrospector serverIntrospector = this.factory.getInstance(clientName, ServerIntrospector.class);

public <T> T getInstance(String name, Class<T> type) {
        AnnotationConfigApplicationContext context = getContext(name);
        if (BeanFactoryUtils.beanNamesForTypeIncludingAncestors(context,
                type).length > 0) {
            return context.getBean(type);
        }
        return null;
    }

3、把创建好的FeignLoadBalancer对象放到集合缓存里。

this.cache.put(clientName, client);

下面是全部的详细源码

package org.springframework.cloud.openfeign.ribbon;

import java.util.Map;

import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryFactory;
import org.springframework.cloud.netflix.ribbon.ServerIntrospector;
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
import org.springframework.util.ConcurrentReferenceHashMap;

import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.ILoadBalancer;

/**
 * Factory for SpringLoadBalancer instances that caches the entries created.
 *
 * @author Spencer Gibb
 * @author Dave Syer
 * @author Ryan Baxter
 * @author Gang Li
 */
public class CachingSpringLoadBalancerFactory {

    private final SpringClientFactory factory;
    private LoadBalancedRetryFactory loadBalancedRetryFactory = null;

    private volatile Map<String, FeignLoadBalancer> cache = new ConcurrentReferenceHashMap<>();

    public CachingSpringLoadBalancerFactory(SpringClientFactory factory) {
        this.factory = factory;
    }

    public CachingSpringLoadBalancerFactory(SpringClientFactory factory, LoadBalancedRetryFactory loadBalancedRetryPolicyFactory) {
        this.factory = factory;
        this.loadBalancedRetryFactory = loadBalancedRetryPolicyFactory;
    }

    public FeignLoadBalancer create(String clientName) {
        FeignLoadBalancer client = this.cache.get(clientName);
        if(client != null) {
            return client;
        }
        IClientConfig config = this.factory.getClientConfig(clientName);
        ILoadBalancer lb = this.factory.getLoadBalancer(clientName);
        ServerIntrospector serverIntrospector = this.factory.getInstance(clientName, ServerIntrospector.class);
        client = loadBalancedRetryFactory != null ? new RetryableFeignLoadBalancer(lb, config, serverIntrospector,
            loadBalancedRetryFactory) : new FeignLoadBalancer(lb, config, serverIntrospector);
        this.cache.put(clientName, client);
        return client;
    }

}

二、几个问题
1、值得参考的是它的cache属性的定义。

    private volatile Map<String, FeignLoadBalancer> cache = new ConcurrentReferenceHashMap<>();

一是它用volatile修饰,二是它采用了ConcurrentMap的一个子类。

public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> 

org.springframework.util.ConcurrentReferenceHashMap能指定所存放对象的引用级别,适用于并发下Map的数据缓存。

在jvm满的时候,会回收掉不可达对象和软引用对象

详细请参考
https://cloud.tencent.com/developer/article/1633098?from=information.detail.concurrentreferencehashmap

相关文章

  • 说一说OpenFeign中的一工厂方法实现

    一、CachingSpringLoadBalancerFactory从类的名字也可以看出来,它是一个具备缓存功能和...

  • 设计模式基础(三)

    工厂方法模式 概述:工厂方法模式中抽象工厂类负责定义创建对象的接口,具体对象的创建工作由继承抽象工厂的具体类实现。...

  • Java 工厂方法模式

    在工厂对象上调用创建方法,生成接口的某个实现的对象 通过这种方式,接口与实现分离 方法接口 工厂方法接口 方法实现...

  • 工厂方法模式-披萨订购

    工厂方法模式介绍 工厂方法模式设计方案:将披萨项目的实例化功能抽象成抽象方法,在不同的口味点餐子类中具体实现。工厂...

  • (五)大话设计模式 - 工厂方法与抽象工厂(IOS版)

    之前有写过一个简单工厂的的demo,接下来来一起实现一下它的升级版:工厂方法和抽象工厂 代码实现 - 工厂方法 我...

  • 【Java】【设计模式】工厂模式

    工厂模式 概述:工厂方法中抽象工厂负责定义创建对象的接口,具体对象的创建工作由继承抽象工厂的具体类实现。 优点:客...

  • PHP设计模式之工厂模式

    工厂模式的实现 简单的工厂模式由三部分组成: 抽象基类:类中定义抽象一些方法,用以在子类中实现; 继承自抽象基类的...

  • java收藏夹

    java中的经典问题solution Java 的静态工厂方法 单例的四种实现方法 Java中的clone方法 J...

  • OpenFeign修改负载均衡策略

    前言 在SpringCloud中,Ribbon可以实现服务调用和负载均衡,而OpenFeign基于注解加接口的服务...

  • 五分钟精通设计模式(三)之工厂方法模式

    工厂方法模式分为三种: 普通工厂方法模式、多个工厂方法模式、静态工厂方法模式 废话不多说,下面直奔主题,实现步骤:...

网友评论

      本文标题:说一说OpenFeign中的一工厂方法实现

      本文链接:https://www.haomeiwen.com/subject/yftprltx.html