Jackson2JsonMessageConverter.class中TypePrecedence.INFERRED配置反序列化位置

版权声明:本文为博主原创文章,未经博主允许不得转载。 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
		}

	}

猜你喜欢

转载自blog.csdn.net/ncuzengxiebo/article/details/82012130
今日推荐