Spring与Kafka自动配置问题集成

时间:2017-03-09 19:05:39

标签: spring spring-boot apache-kafka spring-integration

我正在尝试配置Spring Boot应用程序来使用Kafka消息。添加后:

<!-- https://mvnrepository.com/artifact/org.springframework.kafka/spring-kafka -->
<dependency>
    <groupId>org.springframework.kafka</groupId>
    <artifactId>spring-kafka</artifactId>
    <version>1.1.3.RELEASE</version>
</dependency>

进入我的依赖项并使用@EnableKafka@KafkaListener(topics = "some-topic")注释,我收到以下错误:

...
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'kafkaListenerContainerFactory' available

然后我添加以下配置:

@Bean
public Map<String, Object> consumerConfigs() {

    Map<String, Object> propsMap = new HashMap<>();

    propsMap.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");
    propsMap.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, false);
    propsMap.put(ConsumerConfig.AUTO_COMMIT_INTERVAL_MS_CONFIG, "100");
    propsMap.put(ConsumerConfig.SESSION_TIMEOUT_MS_CONFIG, "15000");
    propsMap.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
    propsMap.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
    propsMap.put(ConsumerConfig.GROUP_ID_CONFIG, "group1");
    propsMap.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");
    return propsMap;
}

@Bean
public ConsumerFactory<String, String> consumerFactory() {

    return new DefaultKafkaConsumerFactory<>(consumerConfigs());
}

@Bean
KafkaListenerContainerFactory<ConcurrentMessageListenerContainer<String, String>> kafkaListenerContainerFactory() {

    ConcurrentKafkaListenerContainerFactory<String, String> factory = new ConcurrentKafkaListenerContainerFactory<>();
    factory.setConsumerFactory(consumerFactory());
    factory.setConcurrency(3);
    factory.getContainerProperties().setPollTimeout(3000);
    return factory;
}

错误消失了。但是,我认为我应该能够使用spring.kafka.listener.*属性自动配置它,正如文档所示。

如果我不能,我想使用自动装配的KafkaProperties。但是,为了能够使用它,我补充说:

<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-autoconfigure -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-autoconfigure</artifactId>
    <version>1.5.2.RELEASE</version>
</dependency>

然后可以导入。当我尝试使用它如下:

@Autowired
private KafkaProperties kafkaProperties;

在我的方法中:

 return kafkaProperties.buildConsumerProperties();

我收到以下错误:

Caused by: java.lang.ClassNotFoundException: org.springframework.boot.context.annotation.DeterminableImports
.

这是一个Maven依赖问题,我假设。

所以我的问题是:

  1. 是否可以在不创建@Bean但仅使用application.properties的情况下配置Kafka配置?
  2. 如果没有,我如何跳过上述手动创建所需的Map对象,但只使用kafkaProperties.buildConsumerProperties()而不会出现上述错误(第二个)?

2 个答案:

答案 0 :(得分:1)

转到http://start.spring.io并选择Kafka;他将为你建立一个项目框架,所有这些都将设置为

波姆:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>kafkademo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>kafkademo</name>
    <description>Demo project for Spring Boot</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.2.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.kafka</groupId>
            <artifactId>spring-kafka</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>


</project>

...道具

spring.kafka.consumer.auto-offset-reset=earliest
spring.kafka.consumer.group-id=myGroup

应用...

@SpringBootApplication
public class KafkademoApplication {

    public static void main(String[] args) throws Exception {
        ConfigurableApplicationContext context = SpringApplication.run(KafkademoApplication.class, args);
        System.out.println("Hit enter to terminate");
        System.in.read();
        context.close();
    }

    @KafkaListener(topics="so8400in")
    public void listen(String in) {
        System.out.println(in);
    }

}

修改

我将监听器更改为

@KafkaListener(topics="so8400in")
public void listen(String in) {
    System.out.println("Received message:" + in);
}

然后发送了这条消息......

$ kafka-console-producer --broker-list localhost:9092 --topic so8400in
test message for so42703487

......并在控制台上......

Received message:test message for so42703487

如果您需要进一步的证明,我可以在GitHub上发布项目。

答案 1 :(得分:0)

据我所知,事实证明这是一个Maven问题。基本上,我使用以下结构处理多模块项目:

────parent
    ├───parent.pom
    ├───module1
    |   └───module1.pom
    └───module2
        └───module2.pom

我的parent.pom有另一个parent元素:

<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-parent -->
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.2.RELEASE</version>
</parent>

基本上将上述parent parent替换为:

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <type>pom</type>
            <version>1.5.2.RELEASE</version>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

根据建议here解决了所有问题(自动配置和能够使用KafkaProperties)。