【问题标题】:@Autowired object is always null [duplicate]@Autowired 对象始终为空 [重复]
【发布时间】:2019-07-28 02:20:33
【问题描述】:

我已经开始使用 spring data elasticsearch 并且一直在查看示例 here

我无法理解 @Autowired 的工作原理。考虑以下几点:

IMessageProcessor.java:

package message.processor;

public interface IMessageProcessor {
    void processMessage();
}

MyMessageProcessor.java

package message.processor;

@Component
public class MyMessageProcessor implements IMessageProcessor {

    @Autowired
    private ArticleServiceImpl articleService;

    private final Author johnSmith = new Author("John Smith");
    private final Author johnDoe = new Author("John Doe");

    @Override
    public void processMessage() {
        Article article = new Article("Spring Data Elasticsearch");
        article.setAuthors(asList(johnSmith, johnDoe));
        article.setTags("elasticsearch", "spring data");
        articleService.save(article);       
    }   
}

MyMessageProcessorIT.java

package message.processor;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = Config.class)
public class MyMessageProcessorIT {

    @Autowired
    private ElasticsearchTemplate elasticsearchTemplate;

    @Before
    public void before() {
        elasticsearchTemplate.deleteIndex(Article.class);
        elasticsearchTemplate.createIndex(Article.class);
    }

    @Test
    void testProcessMessage() {
        MyMessageProcessor msgProcessor = new MyMessageProcessor();
        msgProcessor.processMessage();
    }
}

每当我运行单元测试时,MyMessageProcessor 中的articleService 始终是null。我需要额外的配置才能使自动装配工作吗?所有其他代码与上面链接的 github 存储库中的相同。

我如何确保在我需要使用ArticleServiceImpl 的项目中的任何位置都正确地自动连接?

我似乎有其他帖子有同样的问题,但似乎没有一个解决方案适用于我下面的示例。

【问题讨论】:

  • 这是因为您正在使用 new 关键字手动创建 MyMessageProcessor 的实例。在这种情况下,spring 容器没有创建msgProcessor 实例对象,因此它没有机会向该对象注入ArticleServiceImpl 的实例。您不应手动创建此实例。试试autowire吧。
  • 因为你不允许用spring框架创建MyMessageProcessor,那是因为spring没有注入你的ArticleServiceImpl

标签: java spring spring-boot autowired spring-data-elasticsearch


【解决方案1】:

您没有使用 Spring 创建的 MyMessageProcessor 实例并在此行上创建自己的实例。

MyMessageProcessor msgProcessor = new MyMessageProcessor();

您应该改为在测试类中自动装配 MyMessageProcessor。

【讨论】:

    【解决方案2】:

    因为你不允许使用 spring 框架创建 MyMessageProcessor,那是因为 spring 不会注入你的 ArticleServiceImpl

    @Configuration
    public class Configuration { 
    
    @Bean
    public MyMessageProcessor mymessageProcessor() {
     return new MyMessageProcessor();
    }
    }
    

    那么 @Autowire MyMessageProcessor 在你的测试类中

    【讨论】:

      【解决方案3】:

      @PCL,您帖子中的第一个评论链接提供了完整的答案,但在您的代码中,您有 2 个选择: 1 - 将MyMessageProcessor msgProcessor 自动连线:

      package message.processor;
      
      @RunWith(SpringJUnit4ClassRunner.class)
      @ContextConfiguration(classes = Config.class)
      public class MyMessageProcessorIT {
      
          @Autowired
          private ElasticsearchTemplate elasticsearchTemplate;
      
          @Autowired
          private MyMessageProcessor msgProcessor;
          ...
          @Test
          void testProcessMessage() {
             msgProcessor.processMessage();
          }
      }
      

      或者,您获取应用程序上下文并手动自动装配 bean,在 @Tom 提供的链接中,您可以看到因此提到的手动 bean 查找。如果你想创建一个新的 bean,那么 applicationContext 也有一个 autowire 方法。

      最好的问候, 大卫

      【讨论】:

      • 我已在我的项目中进行了此更改,但现在它在msgProcessor.processMessage() 处出现NullPointerException 失败,因为msgProcessornull。其他类是否需要任何其他配置/注释才能使其正常工作?
      • 我还尝试将 @Configurable 注释添加到 MyMessageProcessor 代替 @Component 并按照 @Tom 提供的链接中的建议通过 new 创建我自己的实例,但它得到了我回到我原来的问题:articleService in MyMessageProcessor is null.
      • @PCL,你有一个@ContextConfiguration(classes = Config.class)Config.class 包含什么。尝试添加到配置类@ComponentScan("message.processor")。路径似乎没有被扫描。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-04
      • 1970-01-01
      • 2019-05-27
      相关资源
      最近更新 更多