如何使用bean构造函数在Spring中创建YAML列表中的bean列表?

时间:2016-10-13 18:42:09

标签: java spring-boot yaml

基于这个问题:
dynamically generate list of beans from .yaml file in confg-server
我想使用他的构造函数而不是setter方式创建服务器bean。

我想要一个 yaml 文件,如:

test.servers:
    -
      name: test
      url: testurl
    -
      name: test2
      url: test2url

我希望有一个包含所有服务器的类:

@ConfigurationProperties(prefix = "test")
@Component
public class RealStateApiClients {
    public List<Server> getServers() {
        return servers;
    }

    public void setServers(List<Server> servers) {
        this.servers = servers;
    }

    List<Server> servers = new LinkedList<>();
}

我希望像这样使用类Server:

public class Server{
    private String name;
    private String url;

    public Server(String name, String url, String pass) {
        this.name = name;
        this.url = url;
    }
}

但是当我启动应用程序时,我有异常

Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.Server]: Is it an abstract class?; nested exception is java.lang.InstantiationException: com.Server
    at org.springframework.beans.BeanUtils.instantiate(BeanUtils.java:80) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
    at org.springframework.beans.AbstractNestablePropertyAccessor.newValue(AbstractNestablePropertyAccessor.java:914) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
    ... 33 common frames omitted
Caused by: java.lang.InstantiationException: com.Server
    at java.lang.Class.newInstance(Class.java:427) ~[na:1.8.0_101]
    at org.springframework.beans.BeanUtils.instantiate(BeanUtils.java:77) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
    ... 34 common frames omitted
Caused by: java.lang.NoSuchMethodException: com.Server.<init>()
    at java.lang.Class.getConstructor0(Class.java:3082) ~[na:1.8.0_101]
    at java.lang.Class.newInstance(Class.java:412) ~[na:1.8.0_101]
    ... 35 common frames omitted

如果我像这样定义服务器,那么所有工作:

public class Server{

    private String name;
    private String url;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }
}

我做错了什么?
谢谢!

2 个答案:

答案 0 :(得分:1)

OMG我犯了春天的新秀错误!

必须将Server类定义为:

public class Server{
    private String name;
    private String url;

    public Server(String name, String url, String pass) {
        this.name = name;
        this.url = url;
    }

    public Server(){}

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }
}

使用默认构造函数。

考虑到没有使用构造函数方法初始化Server类,如果要在构造函数中应用某些逻辑,则此解决方案不起作用,但是您可以使Server具有

public void init(){
  //do something
}

方法和RealStateApiClients类有一个

@PostConstruct
public void initAllServers() {
  for (Server server: servers) {
    server.init();
  }
}

现在我们有每个服务器的初始化逻辑

答案 1 :(得分:0)

不幸的是@ConfigurationProperties类必须有:

  • 默认构造函数
  • 制定者