【问题标题】:Property values in bean class are null in constructorbean 类中的属性值在构造函数中为 null
【发布时间】:2018-11-04 14:36:18
【问题描述】:

我正在尝试在我的服务实现类/bean 中使用我的 application.properties 文件中的值。但是当通过我的config类初始化bean时,属性值全部为null。

配置类:

@Configuration
public class AppConfig {
    @Bean AppServiceImpl appServiceImpl() {
        return new AppServiceImpl();
    }
}

服务类:

@Component
public class AppServiceImpl implements AppService {
    @Value("${value.one}")
    String value_one;

    @Value("${value.two}")
    String value_two;

    @Value("${value.three}")
    String value_three;

    //values are null here
    public AppServiceImpl() {
        functionOne(value_one, value_two, value_three);
    }
}

application.properties(在 src/main/resources 下):

value.one=1
value.two=2
value.three=3

进行一些调试,我可以看到 AppConfig 类找到了属性文件,如果我尝试在那里声明 @Value("${value.one}") String value_one;,它表明它已按预期被赋予值 1

但是在我的 AppServiceImpl 类中,所有的值都是空的。我在这里做错了什么?这应该如何在 Springboot 中正确完成?或者只是春天。

谢谢。

【问题讨论】:

    标签: java spring spring-boot


    【解决方案1】:

    如果您使用构造函数中的值,它们将不会立即可用。实际上,它们是在属性上注入的。这里发生的事情是在 spring 创建了一个实例之后,它会更新属性值。

    如果你想在构造函数中使用这些值,你应该使用构造函数注入。构造函数注入是最佳实践。

    public class AppServiceImpl implements AppService {
        String value_one;
        String value_two;
        String value_three;
    
        //values are null here
        public AppServiceImpl(String value1, String value2, String value3) {
            value_one = value1;
            value_two = value2;
            value_three = value3;
            functionOne(value_one, value_two, value_three);
        }
    }
    

    还有你的配置类

    @Configuration
    public class AppConfig {
        @Bean
        AppServiceImpl appServiceImpl(@Value("${value.one}") String value1,  @Value("${value.two}") String value2,  @Value("${value.three}") String value3) {
            return new AppServiceImpl(value1, value2, value3);
        }
    }
    

    【讨论】:

    • 为什么这比@PostConstruct 函数更可取?
    • 因为要等待上下文完全初始化,所以隐藏了循环依赖,比较难测试。
    • 很公平。谢谢!
    • 最后一点是这样你就可以不依赖于 spring 并且可以在任何项目中重用类。
    • 您的构造函数中有一个小错误:1)您使用的实例变量仍然为空。 2)您没有将注入的值分配给实例变量
    【解决方案2】:

    这些值是在实例创建之后注入的。所以它们在构造函数中是null

    要在注入值后执行方法,请使用@javax.annotation.PostConstruct:

    @PostConstruct
    public void init(){ // method name doesn't matter
         functionOne(value_one, value_two, value_three);
    }
    

    【讨论】:

    • @JEY 是的,您最好使用构造函数注入的答案,但在某些情况下不能使用构造函数注入。例如。在 JUnit 测试用例中
    • 似乎这样有效。但是我应该使用 JEY 的方式来代替构造函数注入?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-12-09
    • 1970-01-01
    • 1970-01-01
    • 2019-05-21
    • 2014-08-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多