Springboot RabbitMq源码解析之RabbitListener的MessageListener#onMessage解析

版权声明:感谢您的阅读,欢迎讨论并指出不足,可自由转载,但请注明出处和作者 https://blog.csdn.net/qq_39470742/article/details/87715202

Springboot RabbitMq源码解析之配置类
Springboot RabbitMq源码解析之消息发送
Springboot RabbitMq源码解析之消费者容器SimpleMessageListenerContainer
Springboot RabbitMq源码解析之consumer管理和AmqpEvent
Springboot RabbitMq源码解析之RabbitListener注解

Springboot RabbitMq源码解析之RabbitListener注解中,我们解析了Springboot中是如何根据RabbitListener注解生成MessageListenerContainer。
Springboot RabbitMq源码解析之消费者容器SimpleMessageListenerContainer,我们以SimpleMessageListenerContainer解析了MessageListener是如何消息rabbitmq消息的。对于messageListener类型的监听器,SimpleMessageListenerContainer最终是通过MessagListener#onMessage方法进行了消息的消费逻辑。
接下来,我们关注的重点是在RabbitListener注解的MessageListener#onMessage处理逻辑。

一、 生成MessageListenerContainer

从上文可以看到,在 RabbitListenerEndpointRegistry#registerListenerContainer中的通过MessageListenerContainer container = createListenerContainer(endpoint, factory);生成MessageListenerContainer。

1. RabbitListenerEndpointRegistry#createListenerContainer

protected MessageListenerContainer createListenerContainer(RabbitListenerEndpoint endpoint,
		RabbitListenerContainerFactory<?> factory) {

	MessageListenerContainer listenerContainer = factory.createListenerContainer(endpoint);

	if (listenerContainer instanceof InitializingBean) {
		try {
			((InitializingBean) listenerContainer).afterPropertiesSet();
		}
		catch (Exception ex) {
			throw new BeanInitializationException("Failed to initialize message listener container", ex);
		}
	}

	int containerPhase = listenerContainer.getPhase();
	if (containerPhase < Integer.MAX_VALUE) {  // a custom phase value
		if (this.phase < Integer.MAX_VALUE && this.phase != containerPhase) {
			throw new IllegalStateException("Encountered phase mismatch between container factory definitions: " +
					this.phase + " vs " + containerPhase);
		}
		this.phase = listenerContainer.getPhase();
	}

	return listenerContainer;
}

点击MessageListenerContainer listenerContainer = factory.createListenerContainer(endpoint);继续跟踪。

2. AbstractRabbitListenerContainerFactory#createListenerContainer

@Override
public C createListenerContainer(RabbitListenerEndpoint endpoint) {
	C instance = createContainerInstance();

	if (this.connectionFactory != null) {
		instance.setConnectionFactory(this.connectionFactory);
	}
	if (this.errorHandler != null) {
		instance.setErrorHandler(this.errorHandler);
	}
	if (this.messageConverter != null) {
		instance.setMessageConverter(this.messageConverter);
	}
	if (this.acknowledgeMode != null) {
		instance.setAcknowledgeMode(this.acknowledgeMode);
	}
	if (this.channelTransacted != null) {
		instance.setChannelTransacted(this.channelTransacted);
	}
	if (this.applicationContext != null) {
		instance.setApplicationContext(this.applicationContext);
	}
	if (this.taskExecutor != null) {
		instance.setTaskExecutor(this.taskExecutor);
	}
	if (this.transactionManager != null) {
		instance.setTransactionManager(this.transactionManager);
	}
	if (this.prefetchCount != null) {
		instance.setPrefetchCount(this.prefetchCount);
	}
	if (this.defaultRequeueRejected != null) {
		instance.setDefaultRequeueRejected(this.defaultRequeueRejected);
	}
	if (this.adviceChain != null) {
		instance.setAdviceChain(this.adviceChain);
	}
	if (this.recoveryBackOff != null) {
		instance.setRecoveryBackOff(this.recoveryBackOff);
	}
	if (this.mismatchedQueuesFatal != null) {
		instance.setMismatchedQueuesFatal(this.mismatchedQueuesFatal);
	}
	if (this.missingQueuesFatal != null) {
		instance.setMissingQueuesFatal(this.missingQueuesFatal);
	}
	if (this.consumerTagStrategy != null) {
		instance.setConsumerTagStrategy(this.consumerTagStrategy);
	}
	if (this.idleEventInterval != null) {
		instance.setIdleEventInterval(this.idleEventInterval);
	}
	if (this.failedDeclarationRetryInterval != null) {
		instance.setFailedDeclarationRetryInterval(this.failedDeclarationRetryInterval);
	}
	if (this.applicationEventPublisher != null) {
		instance.setApplicationEventPublisher(this.applicationEventPublisher);
	}
	if (endpoint.getAutoStartup() != null) {
		instance.setAutoStartup(endpoint.getAutoStartup());
	}
	else if (this.autoStartup != null) {
		instance.setAutoStartup(this.autoStartup);
	}
	if (this.phase != null) {
		instance.setPhase(this.phase);
	}
	if (this.afterReceivePostProcessors != null) {
		instance.setAfterReceivePostProcessors(this.afterReceivePostProcessors);
	}
	instance.setListenerId(endpoint.getId());

	endpoint.setupListenerContainer(instance);
	initializeContainer(instance, endpoint);

	return instance;
}

AbstractRabbitListenerContainerFactory是MessageListener的抽象工厂类,方法中的绝大多数内容都只是给对象属性赋值,需要关注的是endpoint.setupListenerContainer(instance);语句。

3. AbstractRabbitListenerEndpoint#setListenerContainer

@Override
public void setupListenerContainer(MessageListenerContainer listenerContainer) {
	AbstractMessageListenerContainer container = (AbstractMessageListenerContainer) listenerContainer;

	boolean queuesEmpty = getQueues().isEmpty();
	boolean queueNamesEmpty = getQueueNames().isEmpty();
	if (!queuesEmpty && !queueNamesEmpty) {
		throw new IllegalStateException("Queues or queue names must be provided but not both for " + this);
	}
	if (queuesEmpty) {
		Collection<String> names = getQueueNames();
		container.setQueueNames(names.toArray(new String[names.size()]));
	}
	else {
		Collection<Queue> instances = getQueues();
		container.setQueues(instances.toArray(new Queue[instances.size()]));
	}

	container.setExclusive(isExclusive());
	if (getPriority() != null) {
		Map<String, Object> args = new HashMap<String, Object>();
		args.put("x-priority", getPriority());
		container.setConsumerArguments(args);
	}

	if (getAdmin() != null) {
		container.setRabbitAdmin(getAdmin());
	}
	setupMessageListener(listenerContainer);
}
protected abstract MessageListener createMessageListener(MessageListenerContainer container);

private void setupMessageListener(MessageListenerContainer container) {
	MessageListener messageListener = createMessageListener(container);
	Assert.state(messageListener != null, () -> "Endpoint [" + this + "] must provide a non null message listener");
	container.setupMessageListener(messageListener);
}

二、 生成MessageListener

可以看到,上文中生成MessageListener的关键方法AbstractRabbitListenerEndpoint#createMessageListener是一个抽象方法。
AbstractRabbitListenerEndpoint有3个子类,分别SimpleRabbitListenerEndpoint,MethodRabbitListenerEndpoint和MultiMethodRabbitListenerEndpoint,其中MultiMethodRabbitListenerEndpoint是MethodRabbitListenerEndpoint的子类。
回到上文RabbitListenerAnnotationBeanPostProcessor的processAmqpListener和processMultiMethodListeners可以看到,RabbitListener注解对应的endpoint有两种。
(1)当RabbitListener注解在方法上时,对应的endpoint就是MethodRabbitListenerEndpoint。
(2)当RabbitListener注解在类上时,和RabbitHandle注解配合使用,对应的endpoint就是MultiMethodRabbitListenerEndpoint。

1. MethodRabbitListenerEndpoint#createMessageListener

@Override
protected MessagingMessageListenerAdapter createMessageListener(MessageListenerContainer container) {
	Assert.state(this.messageHandlerMethodFactory != null,
			"Could not create message listener - MessageHandlerMethodFactory not set");
	MessagingMessageListenerAdapter messageListener = createMessageListenerInstance();
	messageListener.setHandlerMethod(configureListenerAdapter(messageListener));
	String replyToAddress = getDefaultReplyToAddress();
	if (replyToAddress != null) {
		messageListener.setResponseAddress(replyToAddress);
	}
	MessageConverter messageConverter = container.getMessageConverter();
	if (messageConverter != null) {
		messageListener.setMessageConverter(messageConverter);
	}
	if (getBeanResolver() != null) {
		messageListener.setBeanResolver(getBeanResolver());
	}
	return messageListener;
}

/**
 * Create a {@link HandlerAdapter} for this listener adapter.
 * @param messageListener the listener adapter.
 * @return the handler adapter.
 */
protected HandlerAdapter configureListenerAdapter(MessagingMessageListenerAdapter messageListener) {
	InvocableHandlerMethod invocableHandlerMethod =
			this.messageHandlerMethodFactory.createInvocableHandlerMethod(getBean(), getMethod());
	return new HandlerAdapter(invocableHandlerMethod);
}

/**
 * Create an empty {@link MessagingMessageListenerAdapter} instance.
 * @return the {@link MessagingMessageListenerAdapter} instance.
 */
protected MessagingMessageListenerAdapter createMessageListenerInstance() {
	return new MessagingMessageListenerAdapter(this.bean, this.method, this.returnExceptions, this.errorHandler);
}

可以看到RabbitListener注解对应的MessageListener类型是MessagingMessageListenerAdapter。

2. MultiMethodRabbitListenerEndpoint#configureListenerAdapter

MultiMethodRabbitListenerEndpoint作为MethodRabbitListenerEndpoint的子类,其createMessageListener方法与父类相同,不过其重写了其中的configureListenerAdapter方法。

@Override
protected HandlerAdapter configureListenerAdapter(MessagingMessageListenerAdapter messageListener) {
	List<InvocableHandlerMethod> invocableHandlerMethods = new ArrayList<InvocableHandlerMethod>();
	for (Method method : this.methods) {
		invocableHandlerMethods.add(getMessageHandlerMethodFactory()
				.createInvocableHandlerMethod(getBean(), method));
	}
	this.delegatingHandler = new DelegatingInvocableHandler(invocableHandlerMethods, getBean(), getResolver(),
			getBeanExpressionContext());
	return new HandlerAdapter(this.delegatingHandler);
}

三. HandlerAdapter类

可以看到MethodRabbitListenerEndpoint和MultiMethodRabbitListenerEndpoint对应的都是MessagingMessageListenerAdapter,彼此的最大区别就是handlerMethod不同,为了保持该属性的类型一致,特地新建了一个适配器类:HandlerAdapter。
HandlerAdapter的属性很简单,只有两个:InvocableHandlerMethod和DelegatingInvocableHandler。
其中InvocableHandlerMethod用于MethodRabbitListenerEndpoint,DelegatingInvocableHandler用于MultiMethodRabbitListenerEndpoint,彼此之间没有其他联系。
核心方法是invoke方法,执行InvocableHandlerMethod或者DelegatingInvocableHandler的invoke方法。

public Object invoke(Message<?> message, Object... providedArgs) throws Exception {
	if (this.invokerHandlerMethod != null) {
		return this.invokerHandlerMethod.invoke(message, providedArgs);
	}
	else {
		return this.delegatingHandler.invoke(message, providedArgs);
	}
}

1. InvocableHandlerMethod类

InvocableHandlerMethod类是HandlerMethod类的子类,核心方法是invoke方法,基于接收到的Message和参数执行rabbit的监听方法。

@Nullable
public Object invoke(Message<?> message, Object... providedArgs) throws Exception {
	Object[] args = getMethodArgumentValues(message, providedArgs);
	if (logger.isTraceEnabled()) {
		logger.trace("Invoking '" + ClassUtils.getQualifiedMethodName(getMethod(), getBeanType()) +
				"' with arguments " + Arrays.toString(args));
	}
	Object returnValue = doInvoke(args);
	if (logger.isTraceEnabled()) {
		logger.trace("Method [" + ClassUtils.getQualifiedMethodName(getMethod(), getBeanType()) +
				"] returned [" + returnValue + "]");
	}
	return returnValue;
}

2. DelegatingInvocableHandler类

当RabbitListener注解在类上时,可以同时有多个被RabbitHandle注解的方法用于处理同意queue的消息,因此在DelegatingInvocableHandler类中一个属性rivate final List<InvocableHandlerMethod> handlers;为InvocableHandlerMethod的集合,同样的核心方法也是invoke方法,多了一个根据消息内容的类型选择对应的InvocableHandlerMethod的逻辑。

public Object invoke(Message<?> message, Object... providedArgs) throws Exception {
	Class<? extends Object> payloadClass = message.getPayload().getClass();
	InvocableHandlerMethod handler = getHandlerForPayload(payloadClass);
	Object result = handler.invoke(message, providedArgs);
	if (message.getHeaders().get(AmqpHeaders.REPLY_TO) == null) {
		Expression replyTo = this.handlerSendTo.get(handler);
		if (replyTo != null) {
			result = new AbstractAdaptableMessageListener.ResultHolder(result, replyTo);
		}
	}
	return result;
}

四、MessagingMessageListenerAdapter类

@Override
public void onMessage(org.springframework.amqp.core.Message amqpMessage, Channel channel) throws Exception {
	Message<?> message = toMessagingMessage(amqpMessage);
	if (logger.isDebugEnabled()) {
		logger.debug("Processing [" + message + "]");
	}
	try {
		Object result = invokeHandler(amqpMessage, channel, message);
		if (result != null) {
			handleResult(result, amqpMessage, channel, message);
		}
		else {
			logger.trace("No result object given - no result to handle");
		}
	}
	catch (ListenerExecutionFailedException e) {
		if (this.errorHandler != null) {
			try {
				Object result = this.errorHandler.handleError(amqpMessage, message, e);
				if (result != null) {
					handleResult(result, amqpMessage, channel, message);
				}
				else {
					logger.trace("Error handler returned no result");
				}
			}
			catch (Exception ex) {
				returnOrThrow(amqpMessage, channel, message, ex, ex);
			}
		}
		else {
			returnOrThrow(amqpMessage, channel, message, e.getCause(), e);
		}
	}
}

可以看出,4个核心步骤委托给其它方法处理
(1)Message<?> message = toMessagingMessage(amqpMessage); 消息类型转换
(2)Object result = invokeHandler(amqpMessage, channel, message); 执行消费方法
(3)handleResult(result, amqpMessage, channel, message); 处理执行结果以发送响应
(4)Object result = this.errorHandler.handleError(amqpMessage, message, e); 第(2)步异常时的异常处理
(5)returnOrThrow(amqpMessage, channel, message, ex, ex);异常抛出或返回

1 Message<?> message = toMessagingMessage(amqpMessage);

protected Message<?> toMessagingMessage(org.springframework.amqp.core.Message amqpMessage) {
	return (Message<?>) getMessagingMessageConverter().fromMessage(amqpMessage);
}

进行消息类型转换,将org.springframework.amqp.core.Message类型通过messagingMessageConverter解析成org.springframework.messaging.Message类型,这一点与消息发送时的RabbitTemplate#convertAndSend中的getRequiredMessageConverter().toMessage(object, new MessageProperties())相对应。

2 Object result = invokeHandler(amqpMessage, channel, message);

private Object invokeHandler(org.springframework.amqp.core.Message amqpMessage, Channel channel,
		Message<?> message) {
	try {
		return this.handlerMethod.invoke(message, amqpMessage, channel);
	}
	catch (MessagingException ex) {
		throw new ListenerExecutionFailedException(createMessagingErrorMessage("Listener method could not " +
				"be invoked with the incoming message", message.getPayload()), ex, amqpMessage);
	}
	catch (Exception ex) {
		throw new ListenerExecutionFailedException("Listener method '" +
				this.handlerMethod.getMethodAsString(message.getPayload()) + "' threw exception", ex, amqpMessage);
	}
}

进行消息消费,执行被RabbitListener或RabbitHandler注解的方法逻辑,对于出现的异常封装成ListenerExecutionFailedException抛出。

3 handleResult(result, amqpMessage, channel, message);

protected void handleResult(Object resultArg, Message request, Channel channel, Object source) throws Exception {
	if (channel != null) {
		if (this.logger.isDebugEnabled()) {
			this.logger.debug("Listener method returned result [" + resultArg
					+ "] - generating response message for it");
		}
		try {
			Object result = resultArg instanceof ResultHolder ? ((ResultHolder) resultArg).result : resultArg;
			Message response = buildMessage(channel, result);
			postProcessResponse(request, response);
			Address replyTo = getReplyToAddress(request, source, resultArg);
			sendResponse(channel, replyTo, response);
		}
		catch (Exception ex) {
			throw new ReplyFailureException("Failed to send reply with payload '" + resultArg + "'", ex);
		}
	}
	else if (this.logger.isWarnEnabled()) {
		this.logger.warn("Listener method returned result [" + resultArg
				+ "]: not generating response message for it because no Rabbit Channel given");
	}
}

如果消息的消费方法或者异常处理有执行结果或者异常需要返回时,进入该方法进行响应处理
如果rabbit channel存在,将执行结果封装后作为响应消息返回。

4 Object result = this.errorHandler.handleError(amqpMessage, message, e);

@FunctionalInterface
public interface RabbitListenerErrorHandler {

	/**
	 * Handle the error. If an exception is not thrown, the return value is returned to
	 * the sender using normal {@code replyTo/@SendTo} semantics.
	 * @param amqpMessage the raw message received.
	 * @param message the converted spring-messaging message.
	 * @param exception the exception the listener threw, wrapped in a
	 * {@link ListenerExecutionFailedException}.
	 * @return the return value to be sent to the sender.
	 * @throws Exception an exception which may be the original or different.
	 */
	Object handleError(Message amqpMessage, org.springframework.messaging.Message<?> message,
			ListenerExecutionFailedException exception) throws Exception;

}

当消息的消费方法抛出异常且RabbitListener注解配置了errorHandler时,进入RabbitListenerErrorHandler 的异常处理逻辑。
如果异常处理逻辑有返回值,将其作为消费方法的执行结果需要做(3)中的响应处理。

5 returnOrThrow(amqpMessage, channel, message, ex, ex)

private void returnOrThrow(org.springframework.amqp.core.Message amqpMessage, Channel channel, Message<?> message,
		Throwable throwableToReturn, Exception exceptionToThrow) throws Exception {
	if (!this.returnExceptions) {
		throw exceptionToThrow;
	}
	try {
		handleResult(new RemoteInvocationResult(throwableToReturn), amqpMessage, channel, message);
	}
	catch (ReplyFailureException rfe) {
		if (void.class.equals(this.handlerMethod.getReturnType(message.getPayload()))) {
			throw exceptionToThrow;
		}
		else {
			throw rfe;
		}
	}
}

如果异常处理过程中出现异常或者没有异常处理时,进入该方法进行异常的抛出或返回。
根据RabbitListener注解的returnExceptions属性进行判断,如果为false则直接抛出异常,否则将异常封装成RemoteInvocationResult作为消息消费的执行结果进行(3)中的响应处理。

五、SendTo注解和消息响应

前面分析到,当消费方法的执行结果满足下列条件之一时,会发送响应消息。
(1)消费方法有执行结果
(2)消费方法抛出异常且RabbitListener配置了errorHandler,此时errorHandler的异常处理有返回结果
(3)消费方法抛出异常且RabbitListener没有配置errorHandler(或配置了errorHandler但异常处理也跑出来异常)且RabbitListener的returnExceptions的属性值为true
事实上,我们可以通过与@SendTo注解结合将执行结果发给指定目标,具体方式如下:
(1)RabbitListener注解在方法上时,在同一方法上加上@SendTo注解
(2)RabbitListener注解在类上时,在同一类上加上@SendTo注解或者在该类中被RabbitHandler注解的方法上加上@SendTo注解
同时,需要注意,此时SendTo的value值的数组长度不能超过1,并且SendTo的值支持Bean Spel表达式,但是返回值必须为String或者Address类型。
接下来,同样分两种情况看看代码的逻辑是如何实现的。

1. MessagingMessageListenerAdapter获取目标地址

AbstractAdaptableMessageListener#getReplyToAddress中获取回复地址的逻辑

protected Address getReplyToAddress(Message request, Object source, Object result) throws Exception {
	Address replyTo = request.getMessageProperties().getReplyToAddress();
	if (replyTo == null) {
		if (this.responseAddress == null && this.responseExchange != null) {
			this.responseAddress = new Address(this.responseExchange, this.responseRoutingKey);
		}
		if (result instanceof ResultHolder) {
			replyTo = evaluateReplyTo(request, source, result, ((ResultHolder) result).sendTo);
		}
		else if (this.responseExpression != null) {
			replyTo = evaluateReplyTo(request, source, result, this.responseExpression);
		}
		else if (this.responseAddress == null) {
			throw new AmqpException(
					"Cannot determine ReplyTo message property value: " +
							"Request message does not contain reply-to property, " +
							"and no default response Exchange was set.");
		}
		else {
			replyTo = this.responseAddress;
		}
	}
	return replyTo;
}

可以看出优先级依次是
(1)在消息中的messageProperties中配置replyTo属性。
(2)执行结果为ResultHolder类型,根据其sendTo进行取值。
(3)根据responseExpression属性
(4)根据responseAddress属性
其余情况下则抛出异常

2. RabbitListener注解在方法上

先看MethodRabbitListenerEndpoint#createMessageListener方法中的String replyToAddress = getDefaultReplyToAddress()

@Override
protected MessagingMessageListenerAdapter createMessageListener(MessageListenerContainer container) {
	Assert.state(this.messageHandlerMethodFactory != null,
			"Could not create message listener - MessageHandlerMethodFactory not set");
	MessagingMessageListenerAdapter messageListener = createMessageListenerInstance();
	messageListener.setHandlerMethod(configureListenerAdapter(messageListener));
	String replyToAddress = getDefaultReplyToAddress();
	if (replyToAddress != null) {
		messageListener.setResponseAddress(replyToAddress);
	}
	MessageConverter messageConverter = container.getMessageConverter();
	if (messageConverter != null) {
		messageListener.setMessageConverter(messageConverter);
	}
	if (getBeanResolver() != null) {
		messageListener.setBeanResolver(getBeanResolver());
	}
	return messageListener;
}
private String getDefaultReplyToAddress() {
	Method method = getMethod();
	if (method != null) {
		SendTo ann = AnnotationUtils.getAnnotation(method, SendTo.class);
		if (ann != null) {
			String[] destinations = ann.value();
			if (destinations.length > 1) {
				throw new IllegalStateException("Invalid @" + SendTo.class.getSimpleName() + " annotation on '"
						+ method + "' one destination must be set (got " + Arrays.toString(destinations) + ")");
			}
			return destinations.length == 1 ? resolve(destinations[0]) : "";
		}
	}
	return null;
}

可以看出,当配置了SendTo注解,会调用AbstractAdaptableMessageListener#setResponseAddress进行处理。

public void setResponseAddress(String defaultReplyTo) {
	if (defaultReplyTo.startsWith(PARSER_CONTEXT.getExpressionPrefix())) {
		this.responseExpression = PARSER.parseExpression(defaultReplyTo, PARSER_CONTEXT);
	}
	else {
		this.responseAddress = new Address(defaultReplyTo);
	}
}

responseExpression 或 responseAddress 的值不再为null,符合(3)(4)两种情况。

3. RabbitListener注解在类上

此时MethodRabbitListenerEndpoint#createMessageListener方法中的String replyToAddress = getDefaultReplyToAddress()的值为null。
其处理SendTo的逻辑主要在DelegatingInvocableHandler类,具体逻辑在setupReplyTo方法中。

private void setupReplyTo(InvocableHandlerMethod handler) {
	String replyTo = null;
	Method method = handler.getMethod();
	if (method != null) {
		SendTo ann = AnnotationUtils.getAnnotation(method, private void setupReplyTo(InvocableHandlerMethod handler) {
		String replyTo = null;
		Method method = handler.getMethod();
		if (method != null) {
			SendTo ann = AnnotationUtils.getAnnotation(method, SendTo.class);
			replyTo = extractSendTo(method.toString(), ann);
		}
		if (replyTo == null) {
			SendTo ann = AnnotationUtils.getAnnotation(this.bean.getClass(), SendTo.class);
			replyTo = extractSendTo(this.getBean().getClass().getSimpleName(), ann);
		}
		if (replyTo != null) {
			this.handlerSendTo.put(handler, PARSER.parseExpression(replyTo, PARSER_CONTEXT));
		}
	}.class);
		replyTo = extractSendTo(method.toString(), ann);
	}
	if (replyTo == null) {
		SendTo ann = AnnotationUtils.getAnnotation(this.bean.getClass(), SendTo.class);
		replyTo = extractSendTo(this.getBean().getClass().getSimpleName(), ann);
	}
	if (replyTo != null) {
		this.handlerSendTo.put(handler, PARSER.parseExpression(replyTo, PARSER_CONTEXT));
	}
}

可以看到,先获取方法上的SendTo注解,不存在则去获取类上的SendTo注解。

public Object invoke(Message<?> message, Object... providedArgs) throws Exception {
	Class<? extends Object> payloadClass = message.getPayload().getClass();
	InvocableHandlerMethod handler = getHandlerForPayload(payloadClass);
	Object result = handler.invoke(message, providedArgs);
	if (message.getHeaders().get(AmqpHeaders.REPLY_TO) == null) {
		Expression replyTo = this.handlerSendTo.get(handler);
		if (replyTo != null) {
			result = new AbstractAdaptableMessageListener.ResultHolder(result, replyTo);
		}
	}
	return result;
}

然后在invoke中执行完方法对应的InvocableHandlerMethod 后将执行结果和SendTo注解信息一起封装成AbstractAdaptableMessageListener.ResultHolder返回,符合情况(2)。

猜你喜欢

转载自blog.csdn.net/qq_39470742/article/details/87715202