【问题标题】:Spring: NullPointerException occurs when including a beanSpring:包含 bean 时发生 NullPointerException
【发布时间】:2012-07-03 17:15:48
【问题描述】:

我有一个看起来像

的 bean mongoService
<?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);
        }
}  

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

请告诉我我做错了什么

谢谢

【问题讨论】:

    标签: java spring


    【解决方案1】:

    您不应该使用 NEW 运算符创建“DocumentSaver”,如下所示,从 Spring Application Context 中获取。

    DocumentSaver 保存程序 = new DocumentSaver();

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

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

        【解决方案3】:
        1. 使用 @Component 注释您的 Saver。此处的替代方法会将其声明为您的 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);
            }
        }  
        

        【讨论】:

          【解决方案4】:

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

          如果你想在其中加入 MongoService,你应该让它由 Spring 实例化。

          添加您的 wireup.xml 文件:

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

          然后将此 documentSaver 注入您的测试:

          @Autowired
          private DocumentSaver documentSaver;
          

          你的命名约定不好。

          您的 DocumentSaver 类似乎是一个 DAO(因为它的目的是保存一个 Document)。 因此,使用 @Repository 对其进行注释并将其命名为 DocumentSaverDAO。

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

          【讨论】:

            【解决方案5】:

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

            【讨论】:

              猜你喜欢
              • 2015-01-11
              • 1970-01-01
              • 2018-06-07
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2012-05-12
              • 1970-01-01
              • 2013-11-11
              相关资源
              最近更新 更多