Hystrix获取配置属性HystrixProperty

Hystrix支持很多种方式用来获取配置属性,本地默认,自定义设置,统一配置中心等等,最后都是用的同样的代码进行抽象,本文主要进行解析获取配置的主要方法getProperty(),以HystrixCommandProperties的熔断有效开关为例

private final HystrixProperty<Boolean> circuitBreakerEnabled; // Whether circuit breaker should be enabled.
this.circuitBreakerEnabled = getProperty(propertyPrefix, key, "circuitBreaker.enabled", builder.getCircuitBreakerEnabled(), default_circuitBreakerEnabled);

返回值都用HystrixProperty进行抽象表示,获取属性结果是get()方法;

private static HystrixProperty<Boolean> getProperty(String propertyPrefix, HystrixCommandKey key, String instanceProperty, Boolean builderOverrideValue, Boolean defaultValue) {
        return forBoolean()
                .add(propertyPrefix + ".command." + key.name() + "." + instanceProperty, builderOverrideValue)
                .add(propertyPrefix + ".command.default." + instanceProperty, defaultValue)
                .build();
    }
private static <T> ChainBuilder<T> forType(final Class<T> type) {
        return new ChainBuilder<T>() {
            @Override
            protected Class<T> getType() {
                return type;
            }
        };
    }
    
    public static ChainBuilder<Boolean> forBoolean() {
        return forType(Boolean.class);
    }

初始化ChainBuilder对象,开始add对应的属性,这里的顺序很重要,优先级从高到低,当第一个有值的话就会直接返回。

 public ChainBuilder<T> add(String name, T defaultValue) {
            properties.add(getDynamicProperty(name, defaultValue, getType()));
            return this;
        }
        
        public HystrixDynamicProperty<T> build() {
            if (properties.size() < 1) throw new IllegalArgumentException();
            if (properties.size() == 1) return properties.get(0);
            List<HystrixDynamicProperty<T>> reversed = 
                    new ArrayList<HystrixDynamicProperty<T>>(properties);
            Collections.reverse(reversed);
            ChainProperty<T> current = null;
            for (HystrixDynamicProperty<T> p : reversed) {
                if (current == null) {
                    current = new ChainProperty<T>(p);
                }
                else {
                    current = new ChainProperty<T>(p, current);
                }
            }
            
            return new ChainHystrixProperty<T>(current);
            
        }

获取动态属性配置类,该类会获取当前环境的配置来源,本地默认,自定义设置,统一配置中心等等,一般默认的话就是HystrixDynamicPropertiesSystemProperties,获取属性就是调用的System.getProperty(nm)

private static <T> HystrixDynamicProperty<T> getDynamicProperty(String propName, T defaultValue, Class<T> type) {
        HystrixDynamicProperties properties = HystrixPlugins.getInstance().getDynamicProperties();
        HystrixDynamicProperty<T> p = HystrixDynamicProperties.Util.getProperty(properties, propName, defaultValue, type);
        return p;
    }

获取因为不同的动态属性实现类实现了相同的接口,在这里就直接通过对应的实现类进行获取,

public static <T> HystrixDynamicProperty<T> getProperty(
                HystrixDynamicProperties properties, String name, T fallback, Class<T> type) {
            return (HystrixDynamicProperty<T>) doProperty(properties, name, fallback, type);
        }
        
        private static HystrixDynamicProperty<?> doProperty(
                HystrixDynamicProperties delegate, 
                String name, Object fallback, Class<?> type) {
            if(type == String.class) {
                return delegate.getString(name, (String) fallback);
            }
            else if (type == Integer.class) {
                return delegate.getInteger(name, (Integer) fallback);
            }
            else if (type == Long.class) {
                return delegate.getLong(name, (Long) fallback);
            }
            else if (type == Boolean.class) {
                return delegate.getBoolean(name, (Boolean) fallback);
            }
            throw new IllegalStateException();
        }
HystrixDynamicPropertiesSystemProperties的get方法如下。返回动态属性HystrixDynamicProperty并把它加入到ChainBuilder集合
private List<HystrixDynamicProperty<T>> properties = new ArrayList<HystrixDynamicProperty<T>>();
public HystrixDynamicProperty<Boolean> getBoolean(final String name, final Boolean fallback) {
        return new HystrixDynamicProperty<Boolean>() {
            
            @Override
            public String getName() {
                return name;
            }
            @Override
            public Boolean get() {
                if (System.getProperty(name) == null) {
                    return fallback;
                }
                return Boolean.getBoolean(name);
            }
            
            @Override
            public void addCallback(Runnable callback) {
            }
        };
    }

最后开始执行build()方法,因为最先访问的对象肯定是最外层的对象,刚开始创建的对象肯定是最里层的对象,所以这个时候需要把整个集合进行倒序排列Collections.reverse(reversed);开始用ChainProperty包装动态属性,他有两个构造函数,分别对应最里层对象和外层对象,

 private static class ChainProperty<T> extends ChainLink<T> {

        private final HystrixDynamicProperty<T> sProp;

        public ChainProperty(HystrixDynamicProperty<T> sProperty) {
            super();
            sProp = sProperty;
        }


        public ChainProperty(HystrixDynamicProperty<T> sProperty, ChainProperty<T> next) {
            super(next); // setup next pointer

            sProp = sProperty;
            sProp.addCallback(new Runnable() {
                @Override
                public void run() {
                    logger.debug("Property changed: '{} = {}'", getName(), getValue());
                    checkAndFlip();
                }
            });
            checkAndFlip();
        }

        @Override
        public boolean isValueAcceptable() {
            return (sProp.get() != null);
        }

        @Override
        protected T getValue() {
            return sProp.get();
        }

        @Override
        public String getName() {
            return sProp.getName();
        }
        
    }

当设置第一个属性时,设置父类的next为null,在子类中保存HystrixDynamicProperty<T> sProp

public ChainLink() {
            next = null;
            pReference = new AtomicReference<ChainLink<T>>(this);
            callbacks = new ArrayList<Runnable>();
        }

当设置第二个属性时,设置父类next为前一个属性对象,保存当前属性对象,设置回调函数addCallback,本例无回调函数,查看当前动态属性值是否存在,执行get方法,也就是HystrixDynamicPropertiesSystemProperties的getBoolean方法,如果有值的话,设置AtomicReference<ChainLink<T>> pReference为自己,否则设置为里层对象。最后用对象ChainHystrixProperty包装

 public boolean isValueAcceptable() {
            return (sProp.get() != null);
        }
 protected void checkAndFlip() {
            // in case this is the end node
            if (next == null) {
                pReference.set(this);
                return;
            }

            if (this.isValueAcceptable()) {
                logger.debug("Flipping property: {} to use its current value: {}", getName(), getValue());
                pReference.set(this);
            } else {
                logger.debug("Flipping property: {} to use NEXT property: {}", getName(), next);
                pReference.set(next);
            }

            for (Runnable r : callbacks) {
                r.run();
            }
        }

开始get获取对象this.properties.circuitBreakerEnabled().get(),ChainHystrixProperty#get()=>ChainProperty#get()=>ChainLink#get(),判断当前的原子引用是否是最外层对象,如果是的话直接调用getValue方法,也就是直接调用HystrixDynamicProperty#get(),否则递归里面的对象,最后获取到最后的属性值返回。

 public T get() {
            if (pReference.get() == this) {
                return this.getValue();
            } else {
                return pReference.get().get();
            }
        }

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值