Я пытаюсь создать универсальный c сервис, который будет обрабатывать отправку сообщений в MQ, используя java 11, весеннюю загрузку 2.2.6 и MappingJackson2MessageConverter. Я хочу использовать его в качестве bean-компонента в других своих службах.
Но когда я отправляю сообщение, оно имеет тип интерфейса вместо класса отправляемого объекта.
У меня есть интерфейс Entity
для всех объектов, которые я собираюсь отправить и класс SomeEntity implements Entity
. Таким образом, сообщение имеет «тип» (для массива) [Lcom.company.Entity; вместо [Lcom.company.SomeEntity;.
Интерфейс для службы:
public interface MessageSender<T> {
void send(T[] entities);
}
Реализация по умолчанию:
public class DefaultMessageSender<T extends Entity> implements MessageSender<T> {
private final JmsTemplate jmsTemplate;
public DefaultMessageSender(JmsTemplate jmsTemplate) {
this.jmsTemplate = jmsTemplate;
}
@Override
public void send(T[] entities) {
jmsTemplate.convertAndSend(entities);
}
}
В другой службе весенней загрузки я настраиваю службу как bean:
@Bean
public MessageSender<SomeEntity> customerMessageSender(JmsTemplate jmsTemplate) {
return new DefaultMessageSender<>(jmsTemplate);
}
@Bean
public MessageConverter jacksonJmsMessageConverter() {
MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
converter.setTargetType(MessageType.TEXT);
converter.setTypeIdPropertyName("type");
return converter;
}
Есть ли способ заставить преобразователь использовать класс среды выполнения, а не интерфейс?
Upd.: Было две проблемы: удаление типа, которое заменяет все T с классом Entity в DefaultMessageSender и массивами. SomeEntity [] не является подклассом Entity [], и вы не можете его приводить.
Чтобы решить эту проблему, я заменил массив списком и сделал метод абстрактным, чтобы переопределить его конкретными классами.
@Bean
public MessageSender<SomeEntity> someEntityMessageSender(JmsTemplate jmsTemplate) {
return new AbstractDefaultMessageSender<>(jmsTemplate) {
@Override
protected void send(List<SomeEntity> items) {
var arr = items.toArray(new SomeEntity[0]);
jmsTemplate.convertAndSend(arr);
}
};
}