Spring:包含 bean 时发生 NullPointerException



我有一个豆子mongo服务,看起来像

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.0.xsd">
    <context:property-placeholder location="file:///storage//local.properties"/>
    <bean id="mongoService" class="com.business.persist.MongoService">
    <constructor-arg value="${host}"/>
    <constructor-arg value="${port}"/>
    <constructor-arg value="${database}"/>
    </bean>
</beans>   
  • 我需要将此 bean 包含在一个单独的项目中,所以我为这个项目创建了一个 jar 并添加为 maven 依赖项,看起来像

        <dependency>
            <groupId>com.project</groupId>
            <artifactId>business</artifactId>
            <version>master-SNAPSHOT</version>
        </dependency>   
    
  • 现在,在我需要注入此字段的文件中,我执行以下操作

public class DocumentSaver implements IDocumentSaver {
    @Resource
    private MongoService mongoService;
    public boolean addDocument(Document doc) {
       // do other things
       // add document to mongo   
       mongoService.putDocument(document);
       return true;
    }
}  

然后我按如下方式运行测试

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/com/wireup.xml")
public class DocumentSaverTest extends DocumentCase {
    @Test
    public void loadAndSave() {
             DocumentSaver saver = new DocumentSaver();
             Document doc = new Document();
             // fill the doc
             saver.addDocument(doc);
        }
}  

当我在类似上运行它时,我看到了NullPointerException saver.addDocument(doc);

请告诉我我做错了什么

谢谢

你不应该像下面这样用 NEW 运算符创建 "DocumentSaver",从 Spring Application Context 中获取。

DocumentSaver saver = new DocumentSaver();

如果使用 NEW 操作,Spring 不会注入依赖对象。

我的预感是你的DocumentSaver不是由spring管理的,因此MongoService不是自动连接的。您可以将 DocumentSaver 定义为 spring xml 文件中的 spring bean + 将 MongoService 引用连接到其中,或者对其进行注释(例如作为@Repository或@Component),然后在 xml 文件中使用 component-scan。

其次,您似乎正在通过 new 运算符创建 DocumentSaver 对象。应该从 spring 上下文中获取 bean 以使 MongoService 自动连接。或者,如果您不希望 DocumentSaver 成为弹簧豆,另一种选择是在 DocumentSaver 中使用 @Configurable,它利用了侧面编织。

  1. @Component注释您的保护程序。此处的替代方法是将其声明为 XML 文件上的另一个常规Bean
  2. @Autowired你的MongoService ;
  3. @Autowired您的DocumentSaversaver您的考试课程。

编辑后的类如下。

您的组件将如下所示:

@Component
public class DocumentSaver implements IDocumentSaver {
    @Autowired
    private MongoService mongoService;
    public boolean addDocument(Document doc) {
        // do other things
        // add document to mongo   
        mongoService.putDocument(document);
        return true;
    }
}  

你的测试是这样的:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/com/wireup.xml")
public class DocumentSaverTest extends DocumentCase {
    @Autowired
    DocumentSaver saver;
    @Test
    public void loadAndSave() {
        Document doc = new Document();
        // fill the doc
        saver.addDocument(doc);
    }
}  

如果你用一个新的实例化你的 DocumentSaver,你不会把它放到 Spring 上下文中。所以春天不知道,注射也没有完成。

如果你想有一个

MongoService,你应该让它在Spring上

实例化。

添加您的线路.xml文件:

<bean id="documentSaver" class="com....DocumentSaver" />

然后将此文档保护程序注入到您的测试中:

@Autowired
private DocumentSaver documentSaver;

您的命名约定很糟糕。

你的 DocumentSaver 类似乎是一个 DAO(因为它的目的是持久化一个文档)。因此,用@Repository注释它并将其命名为DocumentSaverDAO。

结合我的答案和Spaeth的答案,它将起作用并且包装得很好。

DocumentSaver应该由 Spring 管理(目前不是,因为你通过 new 创建它),或者编织,以便注入依赖项,例如 MongoService。有关将依赖项注入到使用 new 创建的对象的更多详细信息,请参阅此答案。

相关内容

最新更新