微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Spring Boot application.properties未注册

如何解决Spring Boot application.properties未注册

这是我的代码

    @Component
    @Configuration
    @PropertySource("application.properties")
    public class Program {
    
        @Value("${app.title}")
        private String appTitle;
        
        public Program() {
            System.out.println(appTitle);
        }
 }

application.properties具有

app.title=The Program 

输出null的{​​{1}}实例。

那么,我想念什么? 我尝试了几个例子,没有一个奏效。

解决方法

没什么问题,只是不要在构造函数中这样做...

,

由于appTitle是一个自动装配的字段,因此在最初构造对象之后才设置它。这就是在您的示例中该值仍为null的原因。在这种情况下,bean的构建过程如下:

  1. 调用Program构造函数,创建一个新的Program实例
  2. 在新建的bean上将appTitle字段设置为${app.title}

此的理想解决方案取决于您的目标。如果确实需要构造函数中的值,则可以将其作为自动装配的构造函数参数传递。该值将在构造函数中可用:

@Component
@Configuration
@PropertySource("application.properties")
public class Program {
    public Program(@Value("${app.title}") appTitle) {
        System.out.println(appTitle);
    }
}

如果在构造函数本身中不需要它,但需要它来进行Bean的正确初始化,则可以选择使用@javax.annotation.PostConstruct注释在对象构造之后但在使用之前使用它。可供其他地方使用:

@Component
@Configuration
@PropertySource("application.properties")
public class Program {
    @Value("${app.title}")
    private String appTitle;

    @PostConstruct
    public void printAppTitle() {
        System.out.println(appTitle);
    }
}

最后,如果您在构造时不需要该值,但是在bean的生命周期中需要它,那么您所拥有的将起作用。它只是在构造函数本身的主体中不可用:

@Component
@Configuration
@PropertySource("application.properties")
public class Program {
    @Value("${app.title}")
    private String appTitle;
}
,

在编写此问题的其他答案时,假设目标是创建一个在其创建过程中使用给定属性的Spring托管Bean。但是,根据您在另一个答案中的评论,您似乎想要回答的问题是如何在无参数构造函数中访问外部化属性(由@Value提供的属性)。这是基于您的期望,例如Spring之类的Java控制反转(IoC)容器应允许在无参数构造函数中访问外部化的属性(可能还包括其他依赖项)。在这种情况下,此答案将解决在无参数构造函数中访问属性的特定问题。

虽然有一定方法可以实现此目标,但它们都不是Spring框架的惯用用法。您已经发现,自动构造字段(即使用setter注入初始化的字段)无法在构造函数中访问。

有两个部分来解释为什么会这样。首先,为什么它以编程方式发挥作用?其次,为什么要按原样设计?

Spring文档的setter-based dependency injection部分解决了第一个问题:

基于Setter的DI是通过在调用无参数构造函数或无参数static工厂方法以实例化bean之后,在bean上调用setter方法来实现的。

在这种情况下,这意味着首先使用无参数构造函数创建对象。其次,一旦构造了对象,就在构造的bean上初始化appTitle。由于该字段直到构造对象后才初始化,因此在构造函数中它将具有其默认值null

第二个问题是为什么以这种方式设计Spring,而不是以某种方式访问​​构造函数中的属性。 Spring文档中的constructor-based or setter-based DI?侧栏清楚地表明,通常在处理强制性依赖项时,构造函数参数实际上是惯用的方法。

由于可以混合使用基于构造函数的DI和基于setter的DI,因此,将构造函数用于强制性依赖项,将setter方法或配置方法用于可选性依赖项是一个很好的经验法则。 [...]

Spring团队通常提倡构造函数注入,因为它可以让您将应用程序组件实现为不可变对象,并确保所需的依赖项不为null。此外,注入构造函数的组件始终以完全初始化的状态返回到客户端(调用)代码。 [...]

Setter注入主要应仅用于可以在类中分配合理的默认值的可选依赖项。 [...]

构造该对象所需的属性肯定会归类为强制性依赖项。因此,惯用的Spring用法是在构造函数中传递此必需值。

因此,总而言之,Spring框架不支持尝试在无参数构造函数中访问应用程序属性,并且实际上与建议的框架使用背道而驰。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。