class MeshRegistryListener implements NotifyListener {
    private static int DEFAULT_COPY = 2;
    private MeshRegistry meshRegistry;
    private ConcurrentHashSet<NotifyListener> listeners = new ConcurrentHashSet<>();
    private ImmutableList<URL> meshNodes;
    private URL subscribeUrl;
    private List<URL> backupNodes = null;

    public MeshRegistryListener(MeshRegistry meshRegistry, URL subscribeUrl) {
        this.meshRegistry = meshRegistry;
        URL meshNode = subscribeUrl.createCopy();
        URL meshUrl = meshRegistry.getUrl();
        meshNode.setHost(meshUrl.getHost());
        meshNode.setPort(meshUrl.getPort());
        if (StringUtils.isNotBlank(meshUrl.getParameter(URLParamType.fusingThreshold.getName()))) {
            meshNode.addParameter(URLParamType.fusingThreshold.getName(), meshUrl.getParameter(URLParamType.fusingThreshold.getName()));
        }
        int copy = meshUrl.getIntParameter(MeshRegistry.MESH_PARAM_COPY, DEFAULT_COPY);
        ImmutableList.Builder builder = ImmutableList.builder();
        for (int i = 0; i < copy; i++) {
            builder.add(meshNode);
        }
        this.meshNodes = builder.build();
        this.subscribeUrl = subscribeUrl;
    }

    @Override
    public void notify(URL registryUrl, List<URL> urls) {
        if (!CollectionUtil.isEmpty(urls)) {
            this.backupNodes = urls;
            if (!meshRegistry.isUseMesh()) { // 当前未使用mesh时，直接通知
                doNotify(false);
            }
        }
    }

    // 确定通知时调用。
    // 根据useMesh参数决定通知的节点，因此在调用此方法前需要自行判定是否正在使用mesh。
    public void doNotify(boolean useMesh) {<FILL_FUNCTION_BODY>}

    public List<URL> getUrls() {
        if (!meshRegistry.isUseMesh() && !CollectionUtil.isEmpty(backupNodes)) {
            return backupNodes;
        }
        return meshNodes;
    }

    public List<URL> getBackupNodes() {
        return backupNodes;
    }

    public List<URL> getMeshNodes() {
        return meshNodes;
    }

    public void addListener(NotifyListener listener) {
        listeners.add(listener);
    }

    public boolean removeListener(NotifyListener listener) {
        return listeners.remove(listener);
    }
}

        for (NotifyListener listener : listeners) {
            try {
                if (useMesh) {
                    listener.notify(meshRegistry.getUrl(), meshNodes);
                } else {
                    if (CollectionUtil.isEmpty(backupNodes)) {
                        LoggerUtil.info("mesh registry backupNodes is empty, not notify. url:" + subscribeUrl.toSimpleString());
                        return; // 没有后备节点时，不做通知。
                    }
                    listener.notify(meshRegistry.getUrl(), backupNodes);
                }
            } catch (Exception e) {
                LoggerUtil.warn("MeshRegistryListner notify fail. listner url:" + subscribeUrl.toSimpleString());
            }
        }
    
<no_super_class>