在前面的文章中,我们已经发现了开关的踪影,例如cluster,motan支持多个cluster,当前的cluster因为开关关闭的情况下,就会使用下一个cluster。
1.开关相关的类和接口主要都在包com.weibo.api.motan.switcher下,类Switcher是具体的开关:
public class Switcher { private boolean on = true; private String name; // 开关名 public Switcher(String name, boolean on) {//创建开关 this.name = name; this.on = on; } public String getName() {//开关名称 return name; } /** * isOn: true,服务可用; isOn: false, 服务不可用 * * @return */ public boolean isOn() { return on; } /** * turn on switcher */ public void onSwitcher() {//操作开关为开的状态 this.on = true; } /** * turn off switcher */ public void offSwitcher() { this.on = false; } }
2.开关的服务接口SwitcherService
public interface SwitcherService { /** * 获取接口降级开关 * * @param name * @return */ Switcher getSwitcher(String name); /** * 获取所有接口降级开关 * * @return */ List<Switcher> getAllSwitchers(); /** * 初始化开关。 * * @param switcherName * @param initialValue */ void initSwitcher(String switcherName, boolean initialValue); /** * 检查开关是否开启。 * * @param switcherName * @return true :设置来开关,并且开关值为true false:未设置开关或开关为false */ boolean isOpen(String switcherName); /** * 检查开关是否开启,如果开关不存在则将开关置默认值,并返回。 * * @param switcherName * @param defaultValue * @return 开关存在时返回开关值,开关不存在时设置开关为默认值,并返回默认值。 */ boolean isOpen(String switcherName, boolean defaultValue); /** * 设置开关状态。 * * @param switcherName * @param value */ void setValue(String switcherName, boolean value); /** * register a listener for switcher value change, register a listener twice will only fire once * * @param switcherName * @param listener */ void registerListener(String switcherName, SwitcherListener listener);
3.监听开关变化的接口SwitcherListener,主要是监听开关值的变化,由相关的监听者自行实现
4.SwitcherService的实现类LocalSwitcherService
public class LocalSwitcherService implements SwitcherService { private static ConcurrentMap<String, Switcher> switchers = new ConcurrentHashMap<String, Switcher>();//开关集合map private Map<String, List<SwitcherListener>> listenerMap = new ConcurrentHashMap();//监听器map @Override public Switcher getSwitcher(String name) { return switchers.get(name); } @Override public List<Switcher> getAllSwitchers() { return new ArrayList<Switcher>(switchers.values());//获取当前开关服务下的所有开关 } private void putSwitcher(Switcher switcher) { if (switcher == null) { throw new MotanFrameworkException("LocalSwitcherService addSwitcher Error: switcher is null"); } switchers.put(switcher.getName(), switcher); } @Override public void initSwitcher(String switcherName, boolean initialValue) { setValue(switcherName, initialValue); } @Override public boolean isOpen(String switcherName) { Switcher switcher = switchers.get(switcherName); return switcher != null && switcher.isOn(); } @Override public boolean isOpen(String switcherName, boolean defaultValue) { Switcher switcher = switchers.get(switcherName); if (switcher == null) { switchers.putIfAbsent(switcherName, new Switcher(switcherName, defaultValue)); switcher = switchers.get(switcherName); } return switcher.isOn(); } @Override public void setValue(String switcherName, boolean value) { putSwitcher(new Switcher(switcherName, value)); List<SwitcherListener> listeners = listenerMap.get(switcherName); if(listeners != null) { for (SwitcherListener listener : listeners) { listener.onValueChanged(switcherName, value); } } } @Override public void registerListener(String switcherName, SwitcherListener listener) {//为某个开关添加监听器 synchronized (listenerMap) { if (listenerMap.get(switcherName) == null) { List listeners = Collections.synchronizedList(new ArrayList()); listenerMap.put(switcherName, listeners); listeners.add(listener); } else { List listeners = listenerMap.get(switcherName); if (!listeners.contains(listener)) { listeners.add(listener); } } } } @Override public void unRegisterListener(String switcherName, SwitcherListener listener) {//为某个开关移出监听器 synchronized (listenerMap) { if (listener == null) { listenerMap.remove(switcherName); } else { List<SwitcherListener> listeners = listenerMap.get(switcherName); listeners.remove(listener); } } } }