【问题标题】:Properties are not working in spring-boot based java application属性在基于 spring-boot 的 java 应用程序中不起作用
【发布时间】:2018-05-30 15:20:57
【问题描述】:

我有基于 Spring Boot 的 Java 应用程序。我正在使用 java.util.properties 从 src/main/resources (默认路径)中的 application.properties 文件中读取属性。我刚刚定义了 getter 和 setter 来读取道具。 以下是代码:

public class PropertyReader {

    String host;

    public String getHost() {

        Properties properties = new Properties();
        try {
            File file = ResourceUtils.getFile("classpath:application.properties");
            InputStream in = new FileInputStream(file);
            properties.load(in);
        } catch (IOException e) {

        }
        return host = properties.getProperty("spring.mysql.host");
    }

    public void setHost(String host) {
        this.host = host;
    }

}

现在,在另一个类中,只是创建这个类的对象并尝试调用 getHost() 方法来获取主机 ip 地址。

PropertyReader pr = new PropertyReader();
String host = pr.getHost();
PoolProperties p = new PoolProperties();
p.setUrl("jdbc:mysql://" + host + "/ci");

得到以下异常:

Caused by: java.net.UnknownHostException: null
        at java.net.InetAddress.getAllByName0(InetAddress.java:1280) ~[na:1.8.0_151]
        at java.net.InetAddress.getAllByName(InetAddress.java:1192) ~[na:1.8.0_151]
        at java.net.InetAddress.getAllByName(InetAddress.java:1126) ~[na:1.8.0_151]
        at com.mysql.jdbc.StandardSocketFactory.connect(StandardSocketFactory.java:188) ~[mysql-connector-java-5.1.45.jar!/:5.1.45]
        at com.mysql.jdbc.MysqlIO.<init>(MysqlIO.java:300) ~[mysql-connector-java-5.1.45.jar!/:5.1.45]
        ... 44 common frames omitted

不使用属性类,如果我只是硬编码 IP 地址,它绝对可以正常工作。不知道代码中的问题是什么,所以属性阅读器不起作用。

跟随 application.properties 内容:

spring.mysql.host=35.154.83.162

更新 ::::

这里是更新的代码:

@Component
@Configuration
public class UnitDBHelper {
@Autowired
    private Environment env;

public UnitDBHelper() {

        String host = env.getProperty("spring.mysql.host");     
        PoolProperties p = new PoolProperties();
        InputStream input = null;
        p.setUrl("jdbc:mysql://" + host + "/ci");

}
}

得到 NPE 异常:

Error starting ApplicationContext. To display the auto-configuration report re-run your application with 'debug' enabled.
2018-05-30 15:42:29.532 ERROR 9870 --- [           main] o.s.boot.SpringApplication               : Application startup failed

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'unitDBHelper' defined in URL [jar:file:/tmp/unitdbamqpservice-0.0.1-SNAPSHOT.jar!/BOOT-INF/classes!/com/infy/ci/unitdbamqpservice/UnitDBHelper.class]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.infy.ci.unitdbamqpservice.UnitDBHelper$$EnhancerBySpringCGLIB$$24a2dca6]: Constructor threw exception; nested exception is java.lang.NullPointerException

Caused by: java.lang.NullPointerException: null
        at com.infy.ci.unitdbamqpservice.UnitDBHelper.<init>(UnitDBHelper.java:39) ~[classes!/:0.0.1-SNAPSHOT]
        at com.infy.ci.unitdbamqpservice.UnitDBHelper$$EnhancerBySpringCGLIB$$24a2dca6.<init>(<generated>) ~[classes!/:0.0.1-SNAPSHOT]
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.8.0_151]
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[na:1.8.0_151]
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:1.8.0_151]
        at java.lang.reflect.Constructor.newInstance(Constructor.java:423) ~[na:1.8.0_151]
        at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:142) ~[spring-beans-4.3.14.RELEASE.jar!/:4.3.14.RELEASE]
        ... 27 common frames omitted

【问题讨论】:

  • 为什么不用@Value Spring注解?

标签: java mysql


【解决方案1】:

在 Spring Boot 中,您不需要手动读取属性(特别是 application.properties)。
application.properties (.yml|.yaml) 默认加载到 springEnvironemnt 类中。

@Component
public class PropertyReader {

    @Autowired
    private Environment env;

    public String getHost() {
        return env.getProperty("spring.mysql.host");
    }
}

要使用它,只需自动连接 PropertyReader 并调用 getHost() 方法。
即使你不需要编写这个类,你也可以直接使用Environment类。

编辑(问题更新后)

方案一(使用环境)

将您的构造函数代码移至 init 方法,此时 env 未初始化。

public class UnitDBHelper implements InitializingBean {

    // your autowires

    @Override
    public void afterPropertiesSet() throws Exception {
        // your constructor code,
        // this will be called after injecting all beans
        // use `env` here 
    }
}

解决方案 2(使用 @Value)

@Component
public class UnitDBHelper {

    @Value("${spring.mysql.host}")
    private String host;

    // you can still not use host in constructor
    // as it will be uninitialized 

    //  rest of code
}

【讨论】:

  • 谢谢。用最新的代码更改更新了问题。但现在得到了 NPE。
  • 你甚至可以使用@Value注解
  • @LppEdd 是的,我们可以使用它,但是 env 也可以用于从环境中获取其他值。 Environment 也优于 `@Value`
  • 当然,Environment 是一个更完整的选项,但鉴于他必须从 Spring 属性文件中获取一个值,我认为 @Value 是一种更好的方法。无论哪种方式,您都能完成工作
  • 谢谢大家。 @Hemant,我在这里上传了最新代码:github.com/irfanjs/unitdbamqpservice 没有得到使用什么以及在哪里.. 与初始化和构造函数部分(特别是 spring boot 和“@Component”和“@Value”注释)混淆了你能检查代码吗一次并更新我做错了什么?请....
猜你喜欢
  • 2019-06-09
  • 2021-12-11
  • 2021-12-27
  • 1970-01-01
  • 2020-03-15
  • 1970-01-01
  • 2018-03-15
  • 2021-08-01
  • 1970-01-01
相关资源
最近更新 更多