【问题标题】:Can I use spring @Autowired dependency injection to build multiple instances of a class?我可以使用 spring @Autowired 依赖注入来构建一个类的多个实例吗?
【发布时间】:2020-02-09 22:24:36
【问题描述】:

我有一个带有 2 个参数的构造函数的 vaadin UI 类。它用一些字段构建了一条简单的线,显示数据。在另一个(父)UI 中,我想多次嵌入第一个 UI(子),具体取决于父级中加载的一些数据。所以现在我有两个问题:

  1. 是否可以使用 springs @Autowired 注释将我的子 UI 的多个实例注入到父级?如果是,我该怎么做?
  2. 如何将参数传递给我的 @Autowired 子类的构造函数?

我已经发现,我必须用 @Autowired 注释我的子类的构造函数。

我的带有构造函数的子 UI 类(用 @Autowired 注释)

public class ChildUI {

   private String arg1;
   private String arg2;

   @Autowired
   public ChildUI(String arg1, String arg2){
      this.arg1 = arg1;
      this.arg2 = arg2;
   }

}

在我的父类中,我想做这样的事情(personList 是从数据库中加载的):

public class ParentUI {

   ...
   for(Person p : personList){
      //inject instance of ChildUI here and pass p.getLastName() to arg1 and p.getFirstName() to arg2
   }
   ...

}

我用谷歌搜索了一段时间,但我并没有真正找到我想要的东西。也许我只是不知道要搜索什么关键字。也许有人可以尝试解释该怎么做?

【问题讨论】:

标签: java spring dependency-injection autowired


【解决方案1】:

像往常一样创建ChildUI

  for(Person p : personList){
     ChildUI someChild=nChildUI(p.getLastName(),m.getFirstName());
   }
   ...

someChild做点什么

或者如果ChildUI 注入了一些其他依赖项 - 首先使其具有原型作用域,然后

    @Autowire
    private ApplicationContext ctx;
....
      for(Person p : personList){
         ChildUI someChild=ctx.getBean(ChildUI.class,p.getLastName(),m.getFirstName());
       }

【讨论】:

  • 好的,我明天试试这个。目前,我按照您的建议创建了 ChildUI:ChildUI child = new ChildUI(p.getLastName(), p.getFirstName());。现在我需要在 ChildUI 中注入一个 CrudRepository。因此,如果我将其设为原型范围,我可以在 ChildUI 中使用注入 (@Autowire'd) bean 并仍然创建它的多个实例?
  • 是的 - 在这种情况下,您必须将第二个 sn-p 与 ApplicationContext 一起使用。如果 ChildUI 是原型,则每次调用都会返回新实例。
  • 嗨安东尼奥斯,感谢您的支持。我今晚试过了,但我想我还是有问题。在 ParentUI 中,我添加了一个 private ApplicationContext ctx 并使用 layout.add(ctx.getBean(ChildUI.class, Person p)); 创建了 ChildUI 的实例(我决定传递整个对象,因为我想用它做一些事情)。在我的 ChildUI 中,我有以下注释:@Scope("prototype")@SpringComponent。当我现在在 ChildUIs 构造函数中使用Person p时,我仍然得到NullPointerException。我错过了什么?关于 Person 实例(使用 new ... 创建)?
  • 我现在才知道 :-) 我的错误是,我使用了另一个 bean,它在 ChildUIs 构造函数中注入了@Autowired。我将其移至 @PostConstruct 方法,现在它可以完美运行了。
  • 是的,setter 和 field 注入发生在构造函数注入和调用之后,所以是的,您此时不能使用这些依赖项。 @PostConstruct 是要走的路(或在 ctor 中注入所有依赖项)。
【解决方案2】:

我不确定我是否完全理解你的问题,所以如果这不是你的意思,请告诉我。

为您的 childUI 创建多个实例:这很简单,在您的配置类中创建多个 bean:

@Configuration
public class ApplicationConfiguration {

  @Bean
  public ChildUI firstBean(){
    return new ChildUI(arg1,arg2);
  }

  @Bean
  public ChildUI secondBean(){
    return new ChildUI(otherArg1,otherArg2);
  }

  @Bean
  public ChildUI thirdBean(){
    return new ChildUI(arg1,arg2);
  }
}

多个实例注入到其他 bean:如果你自动装配 bean 类型的集合(或列表),它的所有实例都将被注入到它:

public class ParentUI {

  private final Set<ChildUI> children;

  @Autowired
  public ParentUI(Set<ChildUI> children) {
    this.childern = children;//this will contain all three beans
  }
}

【讨论】:

  • 谢谢,我不知道注入这样的 Set 的可能性。您的建议的问题是,ChildUI 的数量不是静态的,而是取决于用户在 ParentUI 中的输入。所以我最终无法在 Configuration 类中定义 ChildUI 列表。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-19
  • 2019-06-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多