版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ncuzengxiebo/article/details/82012130
1、Jackson2JsonMessageConverter
public Object fromMessage(Message message)
throws MessageConversionException {
Object content = null;
MessageProperties properties = message.getMessageProperties();
if (properties != null) {
String contentType = properties.getContentType();
if (contentType != null && contentType.contains("json")) {
String encoding = properties.getContentEncoding();
if (encoding == null) {
encoding = getDefaultCharset();
}
try {
if (getClassMapper() == null) {
JavaType targetJavaType = getJavaTypeMapper()
.toJavaType(message.getMessageProperties());// 就在toJavaType中
content = convertBytesToObject(message.getBody(),
encoding, targetJavaType);
}
else {
Class<?> targetClass = getClassMapper().toClass(
message.getMessageProperties());
content = convertBytesToObject(message.getBody(),
encoding, targetClass);
}
}
catch (IOException e) {
throw new MessageConversionException(
"Failed to convert Message content", e);
}
}
else {
if (log.isWarnEnabled()) {
log.warn("Could not convert incoming message with content-type ["
+ contentType + "], 'json' keyword missing.");
}
}
}
if (content == null) {
content = message.getBody();
}
return content;
}
2、在接收端会设置InferredArgumentType(MessagingMessageListenerAdapter的内部类MessagingMessageConverterAdapter)
private final class MessagingMessageConverterAdapter extends MessagingMessageConverter {
private final Object bean;
private final Method method;
private final Type inferredArgumentType;
private MessagingMessageConverterAdapter(Object bean, Method method) {
this.bean = bean;
this.method = method;
this.inferredArgumentType = determineInferredType(); // 初始化时取道接收端方法参数类型
if (logger.isDebugEnabled() && this.inferredArgumentType != null) {
logger.debug("Inferred argument type for " + method.toString() + " is " + this.inferredArgumentType);
}
}
@Override
protected Object extractPayload(org.springframework.amqp.core.Message message) {
MessageProperties messageProperties = message.getMessageProperties();
if (this.bean != null) {
messageProperties.setTargetBean(this.bean);
}
if (this.method != null) {
messageProperties.setTargetMethod(this.method);
if (this.inferredArgumentType != null) { // 使用初始化时设置好的接收端方法类型
messageProperties.setInferredArgumentType(this.inferredArgumentType);
}
}
return extractMessage(message);
}
private Type determineInferredType() {
if (this.method == null) {
return null;
}
Type genericParameterType = null;
for (int i = 0; i < this.method.getParameterTypes().length; i++) {
MethodParameter methodParameter = new MethodParameter(this.method, i);
/*
* We're looking for a single non-annotated parameter, or one annotated with @Payload.
* We ignore parameters with type Message because they are not involved with conversion.
*/
if (isEligibleParameter(methodParameter)
&& (methodParameter.getParameterAnnotations().length == 0
|| methodParameter.hasParameterAnnotation(Payload.class))) {
if (genericParameterType == null) {
genericParameterType = methodParameter.getGenericParameterType();
if (genericParameterType instanceof ParameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType) genericParameterType;
if (parameterizedType.getRawType().equals(Message.class)) {
genericParameterType = ((ParameterizedType) genericParameterType)
.getActualTypeArguments()[0];
}
}
}
else {
if (MessagingMessageListenerAdapter.this.logger.isDebugEnabled()) {
MessagingMessageListenerAdapter.this.logger
.debug("Ambiguous parameters for target payload for method " + this.method
+ "; no inferred type header added");
}
return null;
}
}
}
return genericParameterType;
}
/*
* Don't consider parameter types that are available after conversion.
* Message, Message<?> and Channel.
*/
private boolean isEligibleParameter(MethodParameter methodParameter) {
Type parameterType = methodParameter.getGenericParameterType();
if (parameterType.equals(Channel.class)
|| parameterType.equals(org.springframework.amqp.core.Message.class)) {
return false;
}
if (parameterType instanceof ParameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType) parameterType;
if (parameterizedType.getRawType().equals(Message.class)) {
return !(parameterizedType.getActualTypeArguments()[0] instanceof WildcardType);
}
}
return !parameterType.equals(Message.class); // could be Message without a generic type
}
}