Java-Spring:上下文初始化期间的NullPointerException(使用@Component,@ Autowired,context:component-scan)

时间:2016-06-09 16:52:00

标签: java spring

我是Spring的新手,在上下文初始化期间看到NullPointerException。这是错误消息

10:23:43,231 WARN  [ClassPathXmlApplicationContext] Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'RoxourProcessor' defined in file [C:\my_sand\branch\Roxour-client-api\target\classes\company\online\Roxour\api\batchOperations\RoxourProcessor.class]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [company.online.Roxour.api.batchOperations.RoxourProcessor]: Constructor threw exception; nested exception is java.lang.NullPointerException
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'RoxourProcessor' defined in file [C:\my_sand\branch\Roxour-client-api\target\classes\company\online\Roxour\api\operation\RoxourProcessor.class]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [company.online.Roxour.api.batchOperations.RoxourProcessor]: Constructor threw exception; nested exception is java.lang.NullPointerException
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1105)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1050)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:510)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:772)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:839)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:538)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
at company.online.Roxour.api.RoxourMasterProcessor.main(RoxourMasterProcessor.java:170)

在我的context.xml中:

<?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:context="http://www.springframework.org/schema/context"
   xmlns:util="http://www.springframework.org/schema/util"
   xsi:schemaLocation="
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
    http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd">


<!-- Scans within the base package of the application for @Components to configure as beans -->
<context:component-scan base-package="org.online.Roxour.api"/>

以下是主要课程:

package org.online.Roxour.api;

public class RoxourMasterProcessor
{
......

@Autowired
RoxourProcessor processor;

........

public void process()
{
    .......
    processor.runJob();
    ...........
}

public static void main(String args[])
{

    ApplicationContext context = new ClassPathXmlApplicationContext("context.xml");
    LOG.info("Context: " + context);
    RoxourMasterProcessor master = context.getBean( RoxourMasterProcessor.class );

    master.process();

}
}

在子包org.online.Roxour.api.utils中,我有ApplicationEnvironment和RoxourUtil类。像:

package org.online.Roxour.api.utils;

@Component
public class ApplicationEnvironment
{
public ApplicationEnvironment()
{
    Properties properties = new Properties();
    try 
    {
        LOG.info("Initiating Application Environment");
        properties.load( this.getClass().getClassLoader().getResourceAsStream( "application.properties" ) );
        load( properties );
    } 
    catch (Throwable e) 
    {
        String msg = "Error loading environment config.";                       
        LOG.error(msg,e);

        System.exit(1);
    }
}
}

package org.online.Roxour.api.utils;

@Component
@Scope("prototype")
public class RoxourUtil 
{
........

@Autowired
ApplicationEnvironment applicationEnvironment;

.........

}

在另一个子包org.online.Roxour.api.operation中,我有类RoxourProcessor:

package org.online.Roxour.api.operation;

@Component
@Scope("singleton")
public class RoxourProcessor
{

    .........

    private int PAYLOAD_SIZE;

    private int  MAX_READER_THREADS;
    private int  MAX_WORKER_THREADS;

    @Autowired
    ApplicationEnvironment applicationEnvironment;

    @Autowired
    RoxourUtil util;

    public RoxourProcessor()
    {
        PAYLOAD_SIZE = applicationEnvironment.getPayloadSize();
        MAX_READER_THREADS = applicationEnvironment.getMaxReaderThreads();
        MAX_WORKER_THREADS = applicationEnvironment.getMaxWorkerThreads();
    }

    ..............

}

在上下文初始化期间,我看到了:

@Autowired

ApplicationEnvironment applicationEnvironment;

@Autowired

RoxourUtil util;

为空。因此从RoxourProcessor-constructor获取NULLPointerException。

但不明白它是如何找不到那两个自动装配的。我错过了什么?

感谢任何帮助。

由于

1 个答案:

答案 0 :(得分:2)

在构造函数调用之后发生字段注入。 用@PostConstruct方法替换构造函数,你应该没问题。

@PostConstruct public void initialize(){
    PAYLOAD_SIZE = applicationEnvironment.getPayloadSize();
    MAX_READER_THREADS = applicationEnvironment.getMaxReaderThreads();
    MAX_WORKER_THREADS = applicationEnvironment.getMaxWorkerThreads();
}

这就是为什么现场注射(或注射器注射)被认为是个坏主意的众多原因之一。您应该更喜欢构造函数注入,它使您的服务不可变且对测试友好,并且您不会在初始化期间遇到竞争条件。