简体   繁体   English

尝试自动装配时在 spring 托管 class 上获取空指针

[英]Getting nullpointer on a spring managed class when trying to autowire

I am creating a spring boot application to listen from a Rabbit queue and to forward the message to a Kafka stream.我正在创建一个 spring 启动应用程序来侦听 Rabbit 队列并将消息转发到 Kafka stream。 I am trying to @Autowire a Kafka configuring class but I am getting NullPointerException , more surprisingly when I list down all the spring managed beans then it gives me the object name of the class I am trying to @Autowire . I am trying to @Autowire a Kafka configuring class but I am getting NullPointerException , more surprisingly when I list down all the spring managed beans then it gives me the object name of the class I am trying to @Autowire . I am not sure where I am missing.我不确定我在哪里失踪。

Starting class:启动 class:

@SpringBootApplication
@ComponentScan(basePackages = {"com.example.demo.service","com.example.demo.configuration"})
public class RabbitConsumerApplication {
    
    private static ApplicationContext applicationContext;

    public static void main(String[] args) {
        applicationContext = SpringApplication.run(RabbitConsumerApplication.class, args);
        displayAllBeans();
    }
    
    public static void displayAllBeans() {
        String[] allBeanNames = applicationContext.getBeanDefinitionNames();
        for(String beanName : allBeanNames) {
            System.out.println(beanName);
        }
    }
    
}

KafkaProducerService class: KafkaProducerService class:

package com.example.demo.service;

@Component
public class KafkaProducerService {
    
    
    @Autowired
    private KafkaTemplate<?, String> kafkaTemplate;
    
    
    public void getMessageFromMQ(Message  message) throws InterruptedException {
        
        Map<String, Object> configProps = new HashMap<>();
          configProps.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");
          configProps.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
          configProps.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
          DefaultKafkaProducerFactory<Object, Object> defaultKafkaProducerFactory = new DefaultKafkaProducerFactory<>(configProps);
          
          
        kafkaTemplate.send("testTopic",new String(message.getBody()));
        
    }


    @Override
    public String toString() {
        return "KafkaProducerService [kafkaTemplate=" + kafkaTemplate + "]";
    }
    
    

}

KafkaProducerConfig class: KafkaProducerConfig class:

package com.example.demo.configuration;

@Configuration
public class KafkaProducerConfig {

    
    @Bean
    public ProducerFactory<String, String> producerFactory() {
      Map<String, Object> configProps = new HashMap<>();
      configProps.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");
      configProps.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
      configProps.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
      return new DefaultKafkaProducerFactory<>(configProps);
    }
    
    @Bean
    public KafkaTemplate<String, String> kafkaTemplate() {
      return new KafkaTemplate<>(producerFactory());
    }
}

RabbitListenerService class: RabbitListenerService class:

package com.example.demo.service;

public class RabbitListenerService implements MessageListener{
    
    @Autowired
    private KafkaProducerService kafkaProducerService;
    
    
    @Override
    public void onMessage(Message message) {
        System.out.println("message :"+new String(message.getBody()));
        System.out.println("object:"+kafkaProducerService.toString());  //19th line. getting nullpointer on this line   
    }

}

Stack trace:堆栈跟踪:

2021-02-20 13:55:06.750  WARN 5392 --- [tnerContainer-1] s.a.r.l.ConditionalRejectingErrorHandler : Execution of Rabbit message listener failed.

org.springframework.amqp.rabbit.support.ListenerExecutionFailedException: Listener threw exception
    at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.wrapToListenerExecutionFailedExceptionIfNeeded(AbstractMessageListenerContainer.java:1746) ~[spring-rabbit-2.3.4.jar:2.3.4]
    at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:1692) ~[spring-rabbit-2.3.4.jar:2.3.4]
    at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.actualInvokeListener(AbstractMessageListenerContainer.java:1562) ~[spring-rabbit-2.3.4.jar:2.3.4]
    at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:1539) ~[spring-rabbit-2.3.4.jar:2.3.4]
    at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:1530) ~[spring-rabbit-2.3.4.jar:2.3.4]
    at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.executeListener(AbstractMessageListenerContainer.java:1474) ~[spring-rabbit-2.3.4.jar:2.3.4]
    at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.doReceiveAndExecute(SimpleMessageListenerContainer.java:967) ~[spring-rabbit-2.3.4.jar:2.3.4]
    at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.receiveAndExecute(SimpleMessageListenerContainer.java:913) ~[spring-rabbit-2.3.4.jar:2.3.4]
    at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access$1600(SimpleMessageListenerContainer.java:83) ~[spring-rabbit-2.3.4.jar:2.3.4]
    at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.mainLoop(SimpleMessageListenerContainer.java:1288) ~[spring-rabbit-2.3.4.jar:2.3.4]
    at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1194) ~[spring-rabbit-2.3.4.jar:2.3.4]
    at java.base/java.lang.Thread.run(Thread.java:834) ~[na:na]
Caused by: java.lang.NullPointerException: null
    at com.example.demo.service.RabbitListenerService.onMessage(RabbitListenerService.java:19) ~[classes/:na]
    at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:1688) ~[spring-rabbit-2.3.4.jar:2.3.4]
    ... 10 common frames omitted

message :hey you
message :hey you

I just want to @Autowire KafkaProducerService class into RabbitListenerService.我只想将@Autowire KafkaProducerService class 转换为 RabbitListenerService。

ok, i kind of solved the problem.好的,我有点解决了这个问题。 Even if the @autowire was happening but it was actually binding a null object because in RabbitConfig.java, i actually initialized rabbitListenerService with a new keyword and that spring IOC do not handle. Even if the @autowire was happening but it was actually binding a null object because in RabbitConfig.java, i actually initialized rabbitListenerService with a new keyword and that spring IOC do not handle. I changed below way and it solved the issue.我改变了以下方式,它解决了这个问题。

RabbitListenerService.java RabbitListenerService.java

@Component
public class RabbitListenerService implements MessageListener{
    
    @Autowired
    private KafkaProducerService kafkaProducerService;
    
    
    @Override
    public void onMessage(Message message) {
        System.out.println("message :"+new String(message.getBody()));
        System.out.println("object:"+kafkaProducerService.toString());
        
        try {
            kafkaProducerService.getMessageFromMQ(message);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

and then autowired this RabbitListenerService into RabbitConfig然后将这个 RabbitListenerService 自动连接到 RabbitConfig

RabbitConfig.java RabbitConfig.java

@Configuration
public class RabbitConfig {
    
    private static final String my_queue = "TestQueue";
    
    @Autowired
    private RabbitListenerService rabbitListenerService;
    
    
    @Bean
    MessageListenerContainer messageListnerContainer() {
        
        SimpleMessageListenerContainer simpleMessageListenerContainer = new SimpleMessageListenerContainer();
        simpleMessageListenerContainer.setConnectionFactory(connectionFactory());
        simpleMessageListenerContainer.setQueues(myQueue());
        simpleMessageListenerContainer.setMessageListener(rabbitListenerService);
        return simpleMessageListenerContainer;

    }
    
}

From you code it looks like you haven't defined any kafka template beans.从您的代码看来,您还没有定义任何 kafka 模板 bean。 For example:例如:

@Configuration
public class MyKafkaConfig {

    ...

    @Bean
    public KafkaTemplate<String, String> kafkaTemplate() {
        // define a template here
    }
}

The kafka service defined has an injected (autowired) KafkaTemplate<?, String> .定义的 kafka 服务有一个注入(自动装配)的KafkaTemplate<?, String> Has such a bean been defined in a configuration class?是否在配置 class 中定义了这样的 bean?

Please also post your stacktrace.还请发布您的堆栈跟踪。

Try with this, replace package with * , make sure it prints KafkaProducerService in bean list,试试这个,用*替换 package ,确保它在 bean 列表中打印 KafkaProducerService,

Always make practice of creating interface for impl service class始终练习为 impl 服务 class 创建接口

@Component
public class KafkaProducerServiceImpl implements KafkaProducerService

eg例如

    @SpringBootApplication
    @ComponentScan(basePackages = "com.example.demo.*"})
    public class RabbitConsumerApplication {
    
  ...
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM