【问题标题】:Getting NullPointerException when tried to read @Autowired configuration object [duplicate]尝试读取 @Autowired 配置对象时出现 NullPointerException [重复]
【发布时间】:2018-12-10 00:19:08
【问题描述】:

我正在尝试从application.properties 读取一些属性。我创建了一个带有@Component@ConfigurationProperties 注释的配置类。

当我尝试从控制器类访问配置时,它工作正常。但是当我试图从一个组件类访问配置时,它会抛出一个空指针异常。

以下是application.properties 和类。

application.properties

elasticsearch.ip=localhost

InputManagementController.java

@RestController
public class InputManagementController {


    @Autowired
    private Configuration configuration;

    @GetMapping("/crawler/start")
    public String start(){
        try{

            System.out.println(configuration.getIp()); ----> getting value localhost
            ElasticsearchInterface es=new ElasticsearchInterface();
            es.getInputs();
        }catch (Exception e){
            e.printStackTrace();
        }
        return "started";
    }
}

ElasticsearchInterface.java

@Component
public class ElasticsearchInterface {


    @Autowired
    private Configuration configuration;

    public List<Map<String, Object>> getInputs() {
            System.out.println(configuration.getIp()); ---> getting java.lang.NullPointerException here
        return null;

    }

}

配置.java

@Component
@ConfigurationProperties("elasticsearch")
public class Configuration {

    private String ip;
    private int port;
    private String cluster;

    public String getIp() {
        return ip;
    }
    public void setIp(String ip) {
        this.ip = ip;
    }

}

【问题讨论】:

  • 在Configuration.java类@user之上使用Configuration注解代替Component注解
  • @Deadpool 仍然遇到同样的错误
  • 它对我有用,这些类在同一个包中吗?还是不同?并检查这个依赖 org.springframework.bootspring-boot-configuration-processortrue
  • ElasticsearchInterface es=new ElasticsearchInterface(); 不行,你还要注入 ElasticsearchInterface,让它由 Spring 管理。
  • 您做错了,您需要使用@Configuration 注解,以便您的类将在 Spring 上下文中自动创建。因为您没有使用 @Configuration 注释标记您的 Configuration 类,所以它不是作为 bean 创建的,并且您会得到空指针异常。此外,您应该使用 @Value 注释来定义要读取的属性。我已经通过下面的回答解释了如何正确执行此操作。

标签: spring-boot autowired spring-boot-actuator spring-boot-test spring-boot-maven-plugin


【解决方案1】:

A - 如何在 Spring Boot 中从 application.properties 读取自定义属性

A-1) 应用程序属性文件

application.properties 文件的默认位置是 src/main/resources。创建此文件夹以及此文件。假设您的情况,将以下属性放入 application.properties 文件中;

myconfig.ip=192.168.166.42
myconfig.port=8090

A-2) 配置类:AppConfig

为了读取属性文件,你需要一个带有@Configuration 注解的类。对于需要读取的所有属性,您需要带有 @Value 注释的适当字段。此外,您还需要这些带有 @Value 注释的字段的 getter 方法。请注意,将此类命名为“Configuration”是一个非常糟糕的选择,因为还有一个同名的注解,因此我将其命名为“AppConfig”

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;

@Configuration
public class AppConfig {

    @Value("${myconfig.ip}")
    private String ip;

    @Value("${myconfig.port}")
    private int port;

    public String getIp() {
        return ip;
    }

    public int getPort() {
        return port;
    }

}

A-3) 演示

然后你创建上面写的这个 AppConfig 类的一个字段,并用@Autowired 注解标记它。然后就可以轻松读取属性文件了;

@RestController
@RequestMapping("/")
public class InputManagementController {

    @Autowired
    private AppConfig config;

    @RequestMapping("/test")
    public String test() {
        return String.format(
                "Configuration Parameters: Port: %s, Ip: %s", 
                config.getPort(),
                config.getIp()
        );
    }

}

A-4) 输出

B - 解决问题

B-1) InputManagementController.java

@RestController
public class InputManagementController {

    @Autowired
    private AppConfig configuration;

    @Autowired
    private ElasticSearchInterface elasticSearchInterface;

    @GetMapping("/crawler/start")
    public String start() {
        try {

            System.out.println(configuration.getIp());
            es.getInputs();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "started";
    }
}

B-2) ElasticSearchInterface.java

@Component
public class ElasticSearchInterface {

    @Autowired
    private AppConfig configuration;

    public List<Map<String, Object>> getInputs() {
        System.out.println(configuration.getIp());

        return null;
    }

}

B-3) AppConfig.java

@Configuration
public class AppConfig {

    @Value("${myconfig.ip}")
    private String ip;

    @Value("${myconfig.port}")
    private int port;

    public String getIp() {
        return ip;
    }

    public int getPort() {
        return port;
    }

}

【讨论】:

  • 感谢您的详细撰写。我尝试了 AppConfig 类但我仍然遇到同样的错误。我能够读取控制器类中的属性。但我仍然无法读取我的服务类 ElasticsearchInterface 中的属性。仍然抛出空指针异常。
  • 问题在于,您使用的是新运算符而不是使用自动装配。创建一个接口,实现它,然后将该接口用作类中的字段,然后自动装配它。您收到空指针异常的原因是您的类实例不在 Spring Context 上。我更新了我的答案,添加了第二部分。
  • 谢谢。它现在工作:)
  • 感谢 Levent Divilioglu 的撰写。我需要的完美信息量。
猜你喜欢
  • 1970-01-01
  • 2013-12-31
  • 1970-01-01
  • 2018-01-21
  • 1970-01-01
  • 2015-10-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多