springcloudbus 无法监听到消息

原因:spring-boot-devtools导致类加载器不一样,为restartclassloader

BusComsumer.java

@Override
	public void accept(RemoteApplicationEvent event) {
		if (event instanceof AckRemoteApplicationEvent) {
			if (this.properties.getTrace().isEnabled() && !this.serviceMatcher.isFromSelf(event)
					&& this.publisher != null) {
				this.publisher.publishEvent(event);
			}
			// If it's an ACK we are finished processing at this point
			return;
		}

		if (log.isDebugEnabled()) {
			log.debug("Received remote event from bus: " + event);
		}

		if (this.serviceMatcher.isForSelf(event) && this.publisher != null) {
			if (!this.serviceMatcher.isFromSelf(event)) {
				this.publisher.publishEvent(event); //推送事件
			}
			if (this.properties.getAck().isEnabled()) {
				AckRemoteApplicationEvent ack = new AckRemoteApplicationEvent(this, this.serviceMatcher.getBusId(),
						destinationFactory.getDestination(this.properties.getAck().getDestinationService()),
						event.getDestinationService(), event.getId(), event.getClass());
				this.busBridge.ifAvailable(bridge -> bridge.send(ack));
				this.publisher.publishEvent(ack);
			}
		}
		if (this.properties.getTrace().isEnabled() && this.publisher != null) {
			// We are set to register sent events so publish it for local consumption,
			// irrespective of the origin
			this.publisher.publishEvent(new SentApplicationEvent(this, event.getOriginService(),
					event.getDestinationService(), event.getId(), event.getClass()));
		}
	}

 AbstractApplicationContext.java

	protected void publishEvent(Object event, @Nullable ResolvableType eventType) {
		Assert.notNull(event, "Event must not be null");

		// Decorate event as an ApplicationEvent if necessary
		ApplicationEvent applicationEvent;
		if (event instanceof ApplicationEvent) {
			applicationEvent = (ApplicationEvent) event;
		}
		else {
			applicationEvent = new PayloadApplicationEvent<>(this, event);
			if (eventType == null) {
				eventType = ((PayloadApplicationEvent<?>) applicationEvent).getResolvableType();
			}
		}

		// Multicast right now if possible - or lazily once the multicaster is initialized
		if (this.earlyApplicationEvents != null) {
			this.earlyApplicationEvents.add(applicationEvent);
		}
		else {
			getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);//广播事件
		}

		// Publish event via parent context as well...
		if (this.parent != null) {
			if (this.parent instanceof AbstractApplicationContext) {
				((AbstractApplicationContext) this.parent).publishEvent(event, eventType);
			}
			else {
				this.parent.publishEvent(event);
			}
		}
	}

SimpleApplicationEventMulticaster.java


@Override
  public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
    ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
    Executor executor = getTaskExecutor();
    //获取监听器
    for (ApplicationListener<?> listener : getApplicationListeners(event, type)) {
      if (executor != null) {
        executor.execute(() -> invokeListener(listener, event));
      }
      else {
        invokeListener(listener, event);
      }
    }
  }

AbstractApplicationEventMulticaster.java


protected Collection<ApplicationListener<?>> getApplicationListeners(
      ApplicationEvent event, ResolvableType eventType) {

    Object source = event.getSource();
    Class<?> sourceType = (source != null ? source.getClass() : null);
    ListenerCacheKey cacheKey = new ListenerCacheKey(eventType, sourceType);

    // Potential new retriever to populate
    CachedListenerRetriever newRetriever = null;

    // Quick check for existing entry on ConcurrentHashMap
    CachedListenerRetriever existingRetriever = this.retrieverCache.get(cacheKey);
    if (existingRetriever == null) {
      // Caching a new ListenerRetriever if possible
      if (this.beanClassLoader == null ||
          (ClassUtils.isCacheSafe(event.getClass(), this.beanClassLoader) &&
              (sourceType == null || ClassUtils.isCacheSafe(sourceType, this.beanClassLoader)))) {
        newRetriever = new CachedListenerRetriever();
        existingRetriever = this.retrieverCache.putIfAbsent(cacheKey, newRetriever);
        if (existingRetriever != null) {
          newRetriever = null;  // no need to populate it in retrieveApplicationListeners
        }
      }
    }

    if (existingRetriever != null) {
      Collection<ApplicationListener<?>> result = existingRetriever.getApplicationListeners();
      if (result != null) {
        return result;
      }
      // If result is null, the existing retriever is not fully populated yet by another thread.
      // Proceed like caching wasn't possible for this current local attempt.
    }
    //获取所有监听器
    return retrieveApplicationListeners(eventType, sourceType, newRetriever);
  }

AbstractApplicationEventMulticaster.java


private Collection<ApplicationListener<?>> retrieveApplicationListeners(
      ResolvableType eventType, @Nullable Class<?> sourceType, @Nullable CachedListenerRetriever retriever) {

    List<ApplicationListener<?>> allListeners = new ArrayList<>();
    Set<ApplicationListener<?>> filteredListeners = (retriever != null ? new LinkedHashSet<>() : null);
    Set<String> filteredListenerBeans = (retriever != null ? new LinkedHashSet<>() : null);

    Set<ApplicationListener<?>> listeners;
    Set<String> listenerBeans;
    synchronized (this.defaultRetriever) {
      listeners = new LinkedHashSet<>(this.defaultRetriever.applicationListeners);
      listenerBeans = new LinkedHashSet<>(this.defaultRetriever.applicationListenerBeans);
    }

    // Add programmatically registered listeners, including ones coming
    // from ApplicationListenerDetector (singleton beans and inner beans).
    for (ApplicationListener<?> listener : listeners) {
      //支持event类型的监听器
      if (supportsEvent(listener, eventType, sourceType)) {
        if (retriever != null) {
          filteredListeners.add(listener);
        }
        allListeners.add(listener);
      }
    }

    // Add listeners by bean name, potentially overlapping with programmatically
    // registered listeners above - but here potentially with additional metadata.
    if (!listenerBeans.isEmpty()) {
      ConfigurableBeanFactory beanFactory = getBeanFactory();
      for (String listenerBeanName : listenerBeans) {
        try {
          if (supportsEvent(beanFactory, listenerBeanName, eventType)) {
            ApplicationListener<?> listener =
                beanFactory.getBean(listenerBeanName, ApplicationListener.class);
            if (!allListeners.contains(listener) && supportsEvent(listener, eventType, sourceType)) {
              if (retriever != null) {
                if (beanFactory.isSingleton(listenerBeanName)) {
                  filteredListeners.add(listener);
                }
                else {
                  filteredListenerBeans.add(listenerBeanName);
                }
              }
              allListeners.add(listener);
            }
          }
          else {
            // Remove non-matching listeners that originally came from
            // ApplicationListenerDetector, possibly ruled out by additional
            // BeanDefinition metadata (e.g. factory method generics) above.
            Object listener = beanFactory.getSingleton(listenerBeanName);
            if (retriever != null) {
              filteredListeners.remove(listener);
            }
            allListeners.remove(listener);
          }
        }
        catch (NoSuchBeanDefinitionException ex) {
          // Singleton listener instance (without backing bean definition) disappeared -
          // probably in the middle of the destruction phase
        }
      }
    }

    AnnotationAwareOrderComparator.sort(allListeners);
    if (retriever != null) {
      if (filteredListenerBeans.isEmpty()) {
        retriever.applicationListeners = new LinkedHashSet<>(allListeners);
        retriever.applicationListenerBeans = filteredListenerBeans;
      }
      else {
        retriever.applicationListeners = filteredListeners;
        retriever.applicationListenerBeans = filteredListenerBeans;
      }
    }
    return allListeners;
  }

AbstractApplicationEventMulticaster.java

protected boolean supportsEvent(
      ApplicationListener<?> listener, ResolvableType eventType, @Nullable Class<?> sourceType) {

    GenericApplicationListener smartListener = (listener instanceof GenericApplicationListener ?
        (GenericApplicationListener) listener : new GenericApplicationListenerAdapter(listener));
    return (smartListener.supportsEventType(eventType) && smartListener.supportsSourceType(sourceType));
  }

GenericApplicationListenerAdapter.java

@Override
  @SuppressWarnings("unchecked")
  public boolean supportsEventType(ResolvableType eventType) {
    if (this.delegate instanceof GenericApplicationListener) {
      return ((GenericApplicationListener) this.delegate).supportsEventType(eventType);
    }
    else if (this.delegate instanceof SmartApplicationListener) {
      Class<? extends ApplicationEvent> eventClass = (Class<? extends ApplicationEvent>) eventType.resolve();
      return (eventClass != null && ((SmartApplicationListener) this.delegate).supportsEventType(eventClass));
    }
    else {
      return (this.declaredEventType == null || this.declaredEventType.isAssignableFrom(eventType));
    }
  }

ResolvableType.java

public boolean isAssignableFrom(ResolvableType other) {
    return isAssignableFrom(other, null);
  }
  private boolean isAssignableFrom(ResolvableType other, @Nullable Map<Type, Type> matchedBefore) {
    Assert.notNull(other, "ResolvableType must not be null");

    // If we cannot resolve types, we are not assignable
    if (this == NONE || other == NONE) {
      return false;
    }

    // Deal with array by delegating to the component type
    if (isArray()) {
      return (other.isArray() && getComponentType().isAssignableFrom(other.getComponentType()));
    }

    if (matchedBefore != null && matchedBefore.get(this.type) == other.type) {
      return true;
    }

    // Deal with wildcard bounds
    WildcardBounds ourBounds = WildcardBounds.get(this);
    WildcardBounds typeBounds = WildcardBounds.get(other);

    // In the form X is assignable to <? extends Number>
    if (typeBounds != null) {
      return (ourBounds != null && ourBounds.isSameKind(typeBounds) &&
          ourBounds.isAssignableFrom(typeBounds.getBounds()));
    }

    // In the form <? extends Number> is assignable to X...
    if (ourBounds != null) {
      return ourBounds.isAssignableFrom(other);
    }

    // Main assignability check about to follow
    boolean exactMatch = (matchedBefore != null);  // We're checking nested generic variables now...
    boolean checkGenerics = true;
    Class<?> ourResolved = null;
    if (this.type instanceof TypeVariable) {
      TypeVariable<?> variable = (TypeVariable<?>) this.type;
      // Try default variable resolution
      if (this.variableResolver != null) {
        ResolvableType resolved = this.variableResolver.resolveVariable(variable);
        if (resolved != null) {
          ourResolved = resolved.resolve();
        }
      }
      if (ourResolved == null) {
        // Try variable resolution against target type
        if (other.variableResolver != null) {
          ResolvableType resolved = other.variableResolver.resolveVariable(variable);
          if (resolved != null) {
            ourResolved = resolved.resolve();
            checkGenerics = false;
          }
        }
      }
      if (ourResolved == null) {
        // Unresolved type variable, potentially nested -> never insist on exact match
        exactMatch = false;
      }
    }
    if (ourResolved == null) {
      ourResolved = resolve(Object.class);
    }
    Class<?> otherResolved = other.toClass();

    // We need an exact type match for generics
    // List<CharSequence> is not assignable from List<String>
    if (exactMatch ? !ourResolved.equals(otherResolved) : !ClassUtils.isAssignable(ourResolved, otherResolved)) {
      return false;//比较类型
    }

    if (checkGenerics) {
      // Recursively check each generic
      ResolvableType[] ourGenerics = getGenerics();
      ResolvableType[] typeGenerics = other.as(ourResolved).getGenerics();
      if (ourGenerics.length != typeGenerics.length) {
        return false;
      }
      if (matchedBefore == null) {
        matchedBefore = new IdentityHashMap<>(1);
      }
      matchedBefore.put(this.type, other.type);
      for (int i = 0; i < ourGenerics.length; i++) {
        if (!ourGenerics[i].isAssignableFrom(typeGenerics[i], matchedBefore)) {
          return false;
        }
      }
    }

    return true;
  }

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值