- Вопрос или проблема
- Ответ или решение
- 1. Проверьте наличие конфигурации PubSubTemplate
- 2. Проверьте зависимости в pom.xml или build.gradle
- 3. Убедитесь, что классы конфигурации правильно сканируются
- 4. Используйте @Autowired для инъекции PubSubTemplate
- 5. Убедитесь, что pubsubConfiguration правильно настроен
- Итог
Вопрос или проблема
введите описание изображения здесь
Здесь я использовал адаптер канала входящих сообщений pubsub для отправки и приема сообщений от издателя и подписчика. Этот код взят именно из документации Google Cloud Pub/Sub, здесь установлены все необходимые зависимости, и все остальное в порядке.
Ниже я предоставляю код класса inboundConfiguration
import com.google.cloud.spring.pubsub.core.PubSubTemplate;
import com.google.cloud.spring.pubsub.integration.AckMode;
import com.google.cloud.spring.pubsub.integration.inbound.PubSubInboundChannelAdapter;
import com.google.cloud.spring.pubsub.support.BasicAcknowledgeablePubsubMessage;
import com.google.cloud.spring.pubsub.support.GcpPubSubHeaders;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.example.mediumpubsub.config.pubsubConfiguration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.MessageHandler;
@Configuration
@RequiredArgsConstructor
@Slf4j
public class inboundConfiguration {
private final pubsubConfiguration pubsubConfiguration;
@Bean
public PubSubInboundChannelAdapter messageChannelAdapter(
@Qualifier("pubsubInputChannel") MessageChannel inputChannel, PubSubTemplate pubSubTemplate) {
PubSubInboundChannelAdapter adapter =
new PubSubInboundChannelAdapter(pubSubTemplate, pubsubConfiguration.getSubscription());
adapter.setOutputChannel(inputChannel);
adapter.setAckMode(AckMode.MANUAL);
return adapter;
}
@Bean
public MessageChannel pubsubInputChannel() {
return new DirectChannel();
}
@Bean
@ServiceActivator(inputChannel = "pubsubInputChannel")
public MessageHandler messageReceiver() {
return message -> {
log.info("Сообщение пришло! Содержимое: " + new String((byte[]) message.getPayload()));
BasicAcknowledgeablePubsubMessage originalMessage =
message.getHeaders().get(GcpPubSubHeaders.ORIGINAL_MESSAGE, BasicAcknowledgeablePubsubMessage.class);
originalMessage.ack();
};
}
}
это outboundConfiguration для справки
package org.example.mediumpubsub.outbound;
import com.google.cloud.spring.pubsub.core.PubSubTemplate;
import com.google.cloud.spring.pubsub.integration.outbound.PubSubMessageHandler;
import org.example.mediumpubsub.config.pubsubConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.integration.annotation.MessagingGateway;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.messaging.MessageHandler;
public class outboundConfiguration {
private final pubsubConfiguration pubsubConfiguration;
public outboundConfiguration(org.example.mediumpubsub.config.pubsubConfiguration pubsubConfiguration) {
this.pubsubConfiguration = pubsubConfiguration;
}
@Bean
@ServiceActivator(inputChannel = "pubsubOutputChannel")
public MessageHandler messageSender(PubSubTemplate pubsubTemplate) {
return new PubSubMessageHandler(pubsubTemplate, pubsubConfiguration.getTopic());
}
@MessagingGateway(defaultRequestChannel = "pubsubOutputChannel")
public interface PubsubOutboundGateway {
void sendToPubsub(String text);
}
}
и также контроллер для outbound
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/send")
@RequiredArgsConstructor
@Slf4j
public class outboundController {
private outboundConfiguration.PubsubOutboundGateway messagingGateway;
@PostMapping("/pubsub")
public void sendMessage(@RequestParam("message") String message) {
log.info(message);
messagingGateway.sendToPubsub(message);
}
}
мне срочно нужно решение этой проблемы, связанной с pubSubTemplate, потому что в других видео на YouTube эта ошибка не возникает
Ответ или решение
Ошибка, с которой вы столкнулись — "Could not autowire. No beans of ‘PubSubTemplate’ type found", обычно указывает на то, что Spring не может найти бины нужного типа, которые вам необходимы для инъекции. В вашем случае это бин PubSubTemplate
. Давайте пройдемся по нескольким шагам для решения этой проблемы.
1. Проверьте наличие конфигурации PubSubTemplate
Убедитесь, что у вас есть правильно настроенный бин PubSubTemplate
в вашей конфигурации. Это должно выглядеть примерно так:
import com.google.cloud.spring.pubsub.core.PubSubTemplate;
import com.google.cloud.spring.pubsub.core.PubSubTemplateFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class PubSubConfig {
@Bean
public PubSubTemplate pubSubTemplate(PubSubLink pubSubLink) {
return new PubSubTemplate(pubSubLink);
}
}
Обратите внимание, что вам необходимо убедиться, что все зависимости и настройки для PubSubTemplate
правильно настроены.
2. Проверьте зависимости в pom.xml
или build.gradle
Убедитесь, что у вас есть все необходимые зависимости в вашем pom.xml
(для Maven) или build.gradle
(для Gradle). Вот пример необходимых зависимостей для Maven:
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>spring-cloud-gcp-pubsub</artifactId>
</dependency>
Для Gradle:
implementation 'com.google.cloud:spring-cloud-gcp-pubsub'
3. Убедитесь, что классы конфигурации правильно сканируются
Если у вас есть несколько классов конфигурации (inboundConfiguration
, outboundConfiguration
, и т.д.), убедитесь, что они помечены как @Configuration
и находятся в пакете, который будет сканироваться Spring. Например, ваш класс конфигурации должен быть в том же пакете или подпакете, что и основной класс вашего приложения.
4. Используйте @Autowired
для инъекции PubSubTemplate
В вашем классе inboundConfiguration
убедитесь, что вы правильно инъецируете PubSubTemplate
:
@Autowired
private PubSubTemplate pubSubTemplate;
И измените метод messageChannelAdapter
, чтобы использовать инъектированный бин вместо параметра:
@Bean
public PubSubInboundChannelAdapter messageChannelAdapter(
@Qualifier("pubsubInputChannel") MessageChannel inputChannel) {
PubSubInboundChannelAdapter adapter =
new PubSubInboundChannelAdapter(pubSubTemplate, pubsubConfiguration.getSubscription());
adapter.setOutputChannel(inputChannel);
adapter.setAckMode(AckMode.MANUAL);
return adapter;
}
5. Убедитесь, что pubsubConfiguration
правильно настроен
Проверьте ваш класс pubsubConfiguration
, чтобы убедиться, что он возвращает корректные значения для getTopic()
и getSubscription()
, поскольку эти значения критически важны для работы с Pub/Sub.
Итог
Следуя вышеизложенным шагам, вы должны быть в состоянии идентифицировать и устранить проблему с "Could not autowire. No beans of ‘PubSubTemplate’ type found". Убедитесь, что все компоненты правильно связаны и настроены перед запуском приложения. Если проблемы сохраняются, рассмотрите возможность включения отладки для Spring, чтобы получить больше информации о процессе создания контекста.