为什么要明确定义KafkaTemplate bean?

huangapple go评论72阅读模式
英文:

Why explictly define KafkaTemplate beans?

问题

以下是您要翻译的内容:

Spring Kafka参考文档建议显式创建Kafka模板的bean。我正在使用spring-boot-starter 2.3.3和spring-kafka 2.5.5,我注意到您只需创建一个带有通配符类型的生产者工厂,Kafka模板bean就会自动创建。这种方法的缺点是IDE不再能够正确评估是否实际存在@Autowired的Kafka模板bean。优点是在Kafka模板中使用许多不同值类型时可以减少配置。

我是否还有其他原因需要显式定义这些bean呢?

    // 在@Configuration类中

    // 变体:仅定义一个通配符生产者
	@Bean
	public ProducerFactory<String, ?> wildcardProducerFactory(){
		return new DefaultKafkaProducerFactory<>(config, new StringSerializer(), new JsonSerializer<>());
	}

    // 变体:定义特定的生产者和模板
	@Bean
	public ProducerFactory<String, Foo> fooProducerFactory(){
		return new DefaultKafkaProducerFactory<>(config, new StringSerializer(), new JsonSerializer<>());
	}

	@Bean
	public KafkaTemplate<String, Foo> fooKafkaTemplate(){
		return new KafkaTemplate<>(fooProducerFactory());
	}
    // 在@Component类的某处
    // 对两种变体的使用方式相同
	@Autowired
	private KafkaTemplate<String, Foo> fooKafkaTemplate;
英文:

The Spring Kafka reference documentation suggest to create the beans for Kafka templates explicitly. I'm using spring-boot-starter 2.3.3 and spring-kafka 2.5.5 and I noticed that you can just create a producer factory with a wildcard type and the Kafka template beans are created automatically. The downside of this approach is that the IDE can no longer correctly evaluate whether an @Autowired Kafka template bean actually exists. The advantage is less configuration when you use a lot of different value types in Kafka templates.

Are there any other reasons I should define these beans explicitly?

    // In a @Configuration class

    // Variant: Just define a wildcard producer
	@Bean
	public ProducerFactory&lt;String, ?&gt; wildcardProducerFactory(){
		return new DefaultKafkaProducerFactory&lt;&gt;(config, new StringSerializer(), new JsonSerializer&lt;&gt;());
	}

    // Variant: Define specific producer and template
	@Bean
	public ProducerFactory&lt;String, Foo&gt; fooProducerFactory(){
		return new DefaultKafkaProducerFactory(config, new StringSerializer(), new JsonSerializer());
	}

	@Bean
	public KafkaTemplate&lt;String, Foo&gt; fooKafkaTemplate(){
		return new KafkaTemplate&lt;&gt;(fooProducerFactory());
	}

    // Somewhere in a @Component class 
    // Usage here is the same for both variants
	@Autowired
	private KafkaTemplate&lt;String, Foo&gt; fooKafkaTemplate;

答案1

得分: 4

使用Spring Boot,甚至不需要创建ProducerFactory bean。自动配置会为您处理这个问题:https://docs.spring.io/spring-boot/docs/current/reference/html/messaging.html#messaging.kafka

此外,还可以查看KafkaProperties.Producer,了解如何通过配置属性提供序列化程序的更多信息。

在注入bean时,不会考虑泛型:如果其根类型匹配,那么您就可以使用它。在Java中,运行时不会有任何泛型 - 这是类型擦除。

您可能只是被IDE的表示所困惑。并且由于这些bean没有在您的项目中声明,所以IDE无法从类路径中看到它们,尽管它们在运行时由Spring Boot呈现出来。

英文:

With Spring Boot you even don't need to create a ProducerFactory bean. The auto-configuration takes care about that for you: https://docs.spring.io/spring-boot/docs/current/reference/html/messaging.html#messaging.kafka

See also a KafkaProperties.Producer for more info how to provide serializers via configuration properties.

Generics are not taken into account when you inject a bean: if its root type match, then you are good to go. There is no any generics at runtime anyway - type erasure in Java.

You probably just confused by the IDE representation. And since those beans are not declared in your project, it doesn't see them from classpath where they are presented by Spring Boot at runtime.

huangapple
  • 本文由 发表于 2020年8月20日 16:56:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/63501628.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定