由于自动装配失败导致的`NullPointerException`

时间:2015-10-22 06:23:28

标签: java spring autowired properties-file

我重构了Spring doc for creating batch service以实现我的读者独立课程

@Component
@PropertySource("classpath:db-config.properties")
public class CsvReader<Item> extends FlatFileItemReader<Item>{

  @Autowired
  private Environment env;

  public CsvReader() {
    this.setResource(new ClassPathResource(env.getProperty("csv_file.name")));
    this.setLineMapper(new DefaultLineMapper<ImportDataItem>() {
      {
        setLineTokenizer(new DelimitedLineTokenizer() {
          {
            setNames(new String[] { "firstName", "lastName" });
          }
        });
      }
    });
  }
}
NullPointerException抛出

env.getProperty("csv_file.name"),如果它被String的文件名替换,则可以正常工作。我读过another answer&amp;上面的代码看起来不错,所以请你帮我理解为什么Environment env没有自动装配?

[main] INFO org.springframework.context.annotation.AnnotationConfigApplicationContext - Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@5c29bfd: startup date [Thu Oct 22 11:26:18 IST 2015]; root of context hierarchy
[main] INFO org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader - Skipping bean definition for [BeanMethod:name=importDataJob,declaringClass=batch.spring.example.job.ImportDataJob]: a definition for bean 'importDataJob' already exists. This top-level bean definition is considered as an override.
[main] WARN org.springframework.context.annotation.ConfigurationClassEnhancer - @Bean method ScopeConfiguration.stepScope is non-static and returns an object assignable to Spring's BeanFactoryPostProcessor interface. This will result in a failure to process annotations such as @Autowired, @Resource and @PostConstruct within the method's declaring @Configuration class. Add the 'static' modifier to this method to avoid these container lifecycle issues; see @Bean javadoc for complete details.
[main] WARN org.springframework.context.annotation.ConfigurationClassEnhancer - @Bean method ScopeConfiguration.jobScope is non-static and returns an object assignable to Spring's BeanFactoryPostProcessor interface. This will result in a failure to process annotations such as @Autowired, @Resource and @PostConstruct within the method's declaring @Configuration class. Add the 'static' modifier to this method to avoid these container lifecycle issues; see @Bean javadoc for complete details.
[main] WARN org.springframework.context.annotation.AnnotationConfigApplicationContext - Exception encountered during context initialization - cancelling refresh attempt
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'CsvReader' defined in batch.spring.example.job.ImportDataJob: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.batch.item.ItemReader]: Factory method 'CsvReader' threw exception; nested exception is java.lang.NullPointerException
  at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:599)
  at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1123)
  at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1018)
  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:305)
  at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
  at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:301)
  at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:196)
  at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:772)
  at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757)
  at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
  at org.springframework.context.annotation.AnnotationConfigApplicationContext.<init>(AnnotationConfigApplicationContext.java:84)
  at batch.spring.example.ImportDataApp.main(ImportDataApp.java:24)
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.batch.item.ItemReader]: Factory method 'CsvReader' threw exception; nested exception is java.lang.NullPointerException
  at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:189)
  at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:588)
  ... 13 more
Caused by: java.lang.NullPointerException
  at batch.spring.example.job.item_reader.CsvReader.<init>(CsvReader.java:28)
  at batch.spring.example.job.ImportDataJob.CsvReader(ImportDataJob.java:67)
  at batch.spring.example.job.ImportDataJob$$EnhancerBySpringCGLIB$$eb882444.CGLIB$CsvReader$1(<generated>)
  at batch.spring.example.job.ImportDataJob$$EnhancerBySpringCGLIB$$eb882444$$FastClassBySpringCGLIB$$6d548885.invoke(<generated>)
  at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
  at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:309)
  at batch.spring.example.job.ImportDataJob$$EnhancerBySpringCGLIB$$eb882444.CsvReader(<generated>)
  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  at java.lang.reflect.Method.invoke(Method.java:497)
  at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:162)
  ... 14 more
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'CsvReader' defined in batch.spring.example.job.ImportDataJob: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.batch.item.ItemReader]: Factory method 'CsvReader' threw exception; nested exception is java.lang.NullPointerException
  at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:599)
  at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1123)
  at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1018)
  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:305)
  at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
  at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:301)
  at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:196)
  at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:772)
  at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757)
  at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
  at org.springframework.context.annotation.AnnotationConfigApplicationContext.<init>(AnnotationConfigApplicationContext.java:84)
  at batch.spring.example.ImportDataApp.main(ImportDataApp.java:24)
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.batch.item.ItemReader]: Factory method 'CsvReader' threw exception; nested exception is java.lang.NullPointerException
  at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:189)
  at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:588)
  ... 13 more
Caused by: java.lang.NullPointerException
  at batch.spring.example.job.item_reader.CsvReader.<init>(CsvReader.java:28)
  at batch.spring.example.job.ImportDataJob.CsvReader(ImportDataJob.java:67)
  at batch.spring.example.job.ImportDataJob$$EnhancerBySpringCGLIB$$eb882444.CGLIB$CsvReader$1(<generated>)
  at batch.spring.example.job.ImportDataJob$$EnhancerBySpringCGLIB$$eb882444$$FastClassBySpringCGLIB$$6d548885.invoke(<generated>)
  at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
  at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:309)
  at batch.spring.example.job.ImportDataJob$$EnhancerBySpringCGLIB$$eb882444.CsvReader(<generated>)
  at sun.reflect.NativeMethodAccessorImpl.inv    [main] INFO org.springframework.context.annotation.AnnotationConfigApplicationContext - Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@5c29bfd: startup date [Thu Oct 22 11:26:18 IST 2015]; root of context hierarchy
[main] INFO org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader - Skipping bean definition for [BeanMethod:name=importDataJob,declaringClass=batch.spring.example.job.ImportDataJob]: a definition for bean 'importDataJob' already exists. This top-level bean definition is considered as an override.
[main] WARN org.springframework.context.annotation.ConfigurationClassEnhancer - @Bean method ScopeConfiguration.stepScope is non-static and returns an object assignable to Spring's BeanFactoryPostProcessor interface. This will result in a failure to process annotations such as @Autowired, @Resource and @PostConstruct within the method's declaring @Configuration class. Add the 'static' modifier to this method to avoid these container lifecycle issues; see @Bean javadoc for complete details.
[main] WARN org.springframework.context.annotation.ConfigurationClassEnhancer - @Bean method ScopeConfiguration.jobScope is non-static and returns an object assignable to Spring's BeanFactoryPostProcessor interface. This will result in a failure to process annotations such as @Autowired, @Resource and @PostConstruct within the method's declaring @Configuration class. Add the 'static' modifier to this method to avoid these container lifecycle issues; see @Bean javadoc for complete details.
[main] WARN org.springframework.context.annotation.AnnotationConfigApplicationContext - Exception encountered during context initialization - cancelling refresh attempt
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'CsvReader' defined in batch.spring.example.job.ImportDataJob: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.batch.item.ItemReader]: Factory method 'CsvReader' threw exception; nested exception is java.lang.NullPointerException
  at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:599)
  at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1123)
  at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1018)
  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:305)
  at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
  at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:301)
  at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:196)
  at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:772)
  at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757)
  at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
  at org.springframework.context.annotation.AnnotationConfigApplicationContext.<init>(AnnotationConfigApplicationContext.java:84)
  at batch.spring.example.ImportDataApp.main(ImportDataApp.java:24)
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.batch.item.ItemReader]: Factory method 'CsvReader' threw exception; nested exception is java.lang.NullPointerException
  at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:189)
  at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:588)
  ... 13 more
Caused by: java.lang.NullPointerException
  at batch.spring.example.job.item_reader.CsvReader.<init>(CsvReader.java:28)
  at batch.spring.example.job.ImportDataJob.CsvReader(ImportDataJob.java:67)
  at batch.spring.example.job.ImportDataJob$$EnhancerBySpringCGLIB$$eb882444.CGLIB$CsvReader$1(<generated>)
  at batch.spring.example.job.ImportDataJob$$EnhancerBySpringCGLIB$$eb882444$$FastClassBySpringCGLIB$$6d548885.invoke(<generated>)
  at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
  at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:309)
  at batch.spring.example.job.ImportDataJob$$EnhancerBySpringCGLIB$$eb882444.CsvReader(<generated>)
  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  at java.lang.reflect.Method.invoke(Method.java:497)
  at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:162)
  ... 14 more
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'CsvReader' defined in batch.spring.example.job.ImportDataJob: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.batch.item.ItemReader]: Factory method 'CsvReader' threw exception; nested exception is java.lang.NullPointerException
  at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:599)
  at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1123)
  at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1018)
  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:305)
  at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
  at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:301)
  at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:196)
  at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:772)
  at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757)
  at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
  at org.springframework.context.annotation.AnnotationConfigApplicationContext.<init>(AnnotationConfigApplicationContext.java:84)
  at batch.spring.example.ImportDataApp.main(ImportDataApp.java:24)
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.batch.item.ItemReader]: Factory method 'CsvReader' threw exception; nested exception is java.lang.NullPointerException
  at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:189)
  at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:588)
  ... 13 more
Caused by: java.lang.NullPointerException
  at batch.spring.example.job.item_reader.CsvReader.<init>(CsvReader.java:28)
  at batch.spring.example.job.ImportDataJob.CsvReader(ImportDataJob.java:67)
  at batch.spring.example.job.ImportDataJob$$EnhancerBySpringCGLIB$$eb882444.CGLIB$CsvReader$1(<generated>)
  at batch.spring.example.job.ImportDataJob$$EnhancerBySpringCGLIB$$eb882444$$FastClassBySpringCGLIB$$6d548885.invoke(<generated>)
  at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
  at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:309)
  at batch.spring.example.job.ImportDataJob$$EnhancerBySpringCGLIB$$eb882444.CsvReader(<generated>)
  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  at java.lang.reflect.Method.invoke(Method.java:497)
  at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:162)
  ... 14 more

1 个答案:

答案 0 :(得分:1)

这一切都归结为如何构造和自动装配对象。要构造一个对象,必须调用构造函数。然后你有一个对象的引用,并可以设置其字段。这就是Spring在创建bean并自动装配它时所做的事情:它调用构造函数,然后设置所有注释为@Autowired的字段。它在调用构造函数之前无法设置字段,因为它还没有任何对象。

但是你的构造函数试图在构造对象之前访问应该由Spring自动装配的字段。这不可能发生。

要从构造函数访问自动装配的bean,必须使用构造函数注入。另一种选择是将所有这些代码从构造函数移动到使用@PostConstruct注释的方法。