当前位置: 首页 > 知识库问答 >
问题:

为什么spring框架不将我的YAML列表绑定到实体?

杜辰龙
2023-03-14

我正在尝试使用@ConfigurationProperties注释将对象列表绑定到实体类。Spring Boot框架似乎忽略了这个注释,实际上它什么都不做。

这是我的申请表。yml属性文件:

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/search-engine
    username: landsreyk
    password: 12345678
  jpa:
    database-platform: org.hibernate.dialect.MySQLDialect
    show-sql: false
    hibernate:
      ddl-auto: none
sites:
  - url: http://someurl1.com
    name: somename1
  - url: https://someurl2.com
    name: somename2
  - url: https://someurl3.com
    name: somename3

这是我的实体类:

package main.model;

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

import javax.persistence.*;
import java.sql.Timestamp;

@Getter
@Setter
@ToString
@Entity
@Table(name = "_site")
public class Site {
    @Column(nullable = false)
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    @Enumerated(EnumType.STRING)
    @Column(name = "status")
    private Status status;

    @Column(name = "status_time")
    private Timestamp statusTime;

    @Column(name = "last_error")
    private String lastError;

    private String url;

    private String name;

    public enum Status {
        INDEXING, INDEXED, FAILED
    }
}

绑定非常简单:

package main.utilities;

import lombok.Getter;
import lombok.Setter;
import main.model.Site;
import org.springframework.boot.context.properties.ConfigurationProperties;

import java.util.List;

@ConfigurationProperties
public class ApplicationProperties {

    @Getter
    @Setter
    private List<Site> sites;

}

在应用程序的某个地方,我正在测试该绑定,比如说我在API中创建了endpoint来测试该绑定,即我的控制器调用一个只打印列表中所有对象的方法:

package main.application.indexer;

import main.utilities.ApplicationProperties;
import org.springframework.beans.factory.annotation.Autowired;

public class IndexBuilder {
    @Autowired
    private ApplicationProperties properties;

    public void run() {
        System.out.println(properties.getSites());
    }

}

预期:

启动后,ApplicationProperties实例不为null。正在调用属性。getSites()返回站点对象的列表。每个站点对象都有从yaml源初始化的url和名称字段。

实际值:

启动后ApplicationProperties实例为null。

我震惊地意识到Spring无法完成如此简单的绑定。知道仅仅解析yaml文件并不是一项很难完成的任务,我认为Spring框架应该内置此功能。如何绑定列表?

顺便说一下,这是我的项目结构。

我编辑了IndexBuilder类。添加了@配置和@Bean注释。现在看起来是这样的:

package main.application.indexer;

import main.utilities.ApplicationProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class IndexBuilder {
    @Autowired
    private ApplicationProperties properties;

    @Bean
    public void run() {
        System.out.println(properties.getSites());
    }

}

这解决了初始化问题,但Spring框架在启动后立即调用run()。这不是预期的行为。

这个用户的回答是完全真实的。他是对的。

共有2个答案

申屠喜
2023-03-14

事实证明,Spring并不像我想象的那么聪明。

要访问@ConfigurationProperties类,即:从非Spring托管类访问bean,-我必须浏览这篇文章:

将Springbean自动关联到非Spring管理的类中https://dzone.com/articles/autowiring-spring-beans-into-classes-not-managed-by-spring

它解决了问题。

羊毅庵
2023-03-14

您应该在您的IndexBuilder类上使用组件,而不是使用配置。

@Configuration应仅用于定义应用程序bean的配置类。在这里,实际上期望用@Bean注释的方法在应用程序启动时立即执行。这是Spring创建所有需要的bean的阶段。但是我想知道Spring接受带有@Bean注释的val方法。

执行run方法的预期时间是什么时候?例如,对于普通bean/组件/服务,您可以在方法上使用PostConstruct注释。然而,这些将与Bean方法在同一阶段执行,或者至少不会太晚。

 类似资料:
  • 因此,我一直在尝试将我的YAML属性中的list属性添加到我创建的类中,不知何故,list绑定只能从YAML中识别逗号分隔的值。 鉴于这门课 还有这个yaml文件 如果我在某处the并打印,它将返回一个空列表,但如果我将yaml文件更改为此 然后绑定工作并返回一个包含值的数组列表。绑定有什么问题?

  • 如何将YAML列表加载到Spring框架项目中的Java列表(没有springboot)? 我看到它在springboot项目中与一起工作。但我无法让它在纯spring框架项目中使用。似乎注释无法正确解析列表。 下面是一个示例项目:https://github.com/KiranMohan/spring-yaml. 为了加载yaml文件,我使用了。 代码在jUnit类中进行测试。 输出is 示例y

  • 问题内容: 我正在使用spring-data-rest将实体公开为(分页的)rest资源。一切正常,但是当我通过请求数据时RestTemplate,我得到了一个无用的HATEOAS JSON(我没有要求)。JSON似乎是。我可以接受,但是JSON无法正确转换为对象。没有里面。 Repository: Client: System.out: curl: 似乎未正确映射到内容?! 问题答案: 正如你已

  • 问题内容: 我希望有人能提供帮助。但是,每当我运行我的代码并尝试查看所有代码时,我都回到列表框中。 谁能看到原因? 码: 问题答案: 即使设置了列表框的和,我也总是要处理此问题。 您当前的代码正确无误,并且可以正常工作,如果您需要访问任意列的当前选定项目值,则可以让他们这样做: 我希望获得完整的结果是,如果您有更多的列,您仍然可以访问它们的值并对其进行任何操作。

  • 将W,S和I,k绑定到乒乓球的左右桨。根据Eclipse,代码进入类p1_upaction扩展AbstractAction,但不运行公共void actionPerform(ActionEvent e)。我不知道该怎么办。键输入称为操作未注册。

  • 我正在将一个项目升级到Spring Boot 2.2.6。在编译错误之后,将yaml属性数据绑定到对象列表- **请注意,该项目是在我使用的以前版本的spring boot(2.2.1)中编译的** JAVAlang.IllegalStateException:未能加载ApplicationContext,原因是:org。springframework。靴子上下文属性。ConfigurationP