首页 > 解决方案 > 使用@Value 创建资源类型构造函数会引发 BeanCreationException;嵌套的 NullPointerException

问题描述

我正在编写一个 springboot 项目,我从 application.properties 中选择一个 .properties 文件

应用程序属性

sample.prop.file=com.example.handler/signature.properties

并创建了一个组件来将此文件作为 InputStream 传递并初始化 Bean

处理程序.java

@Component
public class Handler extends DefaultHandler {

private Resource properties;

public Handler(@Value("${sample.prop.file}") Resource properties) throws IOException {
    this.properties = properties;
    this.props = new Properties();
    this.props.load(this.properties.getInputStream());
  }
}

在我的服务中,我创建了一个 Handler.java 实例并将其添加为 BindingProvider

服务.java

@Service
public class Service {

@Autowired
private Handler handler;

public void doSomething() {
    //some logic
    someMethod(handler);
}

在遵循一些类似的查询之后,我正在尝试构造函数注入并在我的服务中使用 @Autowired 以确保我的 @Component 在被调用之前被初始化。但仍然在运行项目时,我在下面遇到错误。

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'Handler' defined in file [/Users/abc/APP/testService/target/classes/com/example/handler/Handler.class]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.example.handler.Handler]: Constructor threw exception; nested exception is java.lang.NullPointerException
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1320)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1214)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:557)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1287)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1207)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:636)
... 32 common frames omitted

任何输入/评论都是适用的。谢谢!

标签: javaspringspring-boot

解决方案


You should know that Resource is annotation and you can't create an instance of it.

So you may change properties from Resource to String because @Value("${sample.prop.file}") returns String. Your class may become like so:

@Component
public class Handler extends DefaultHandler {

    private Properties props;

    public Handler(@Value("${sample.prop.file}") String properties) throws IOException 
    {
        this.props = new Properties();
        String p =  Paths.get(properties).toAbsolutePath().toString();
        InputStream in = new FileInputStream(p);
        this.props.load(in);
    }
}

But make sure that the new file is accessable, i.e. in some absolute path!


推荐阅读