我有一个豆子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,它利用了侧面编织。
- 用
@Component
注释您的保护程序。此处的替代方法是将其声明为 XML 文件上的另一个常规Bean
。 -
@Autowired
你的MongoService
; -
@Autowired
您的DocumentSaver
以saver
您的考试课程。
编辑后的类如下。
您的组件将如下所示:
@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
创建的对象的更多详细信息,请参阅此答案。