为了账号安全,请及时绑定邮箱和手机立即绑定

如何在没有应用程序的Spring服务类中请求原型豆

如何在没有应用程序的Spring服务类中请求原型豆

扬帆大鱼 2022-08-03 10:35:07
我有一个用原型范围定义的组件。我想在我的服务类中使用该组件。我希望春天每次我呼唤它时都能为我提供一个新的豆子实例。组件类:@Getter@Setter@Component@Scope("prototype")public class ProtoTypeBean {  //.. Field variables}服务等级:@AllArgsConstructor@Servicepublic class ServiceClass {    ProtoTypeBean prototypeBean;    ArrayList<ProtoTypeBean> prototypeBeans;    public void demoMethod(ArrayList<String> someArrayList) {        for(var singleString: someArrayList) {            prototypeBean.setFieldValue(singleString);            prototypeBeans.add(prototypeBean);                      }        System.out.println(prototypeBeans.toString());    }}通过使用此配置,我在我的原型Beans ArrayList中获得了相同的ProtoTypeBean实例。问题是,我如何让Spring理解每次我将其调用到foreach循环中时都给我一个新的原型Bean实例?我发现我可以使用 ApplicationContext.getBean() 在 foreach 循环中获取 Bean 的新实例,但我也听说这是一个不好的做法。因此,请帮助我进行最佳实践。
查看完整描述

3 回答

?
潇潇雨雨

TA贡献1833条经验 获得超4个赞

使用 ObjectProvider 懒洋洋地获得所需的结果。然而,第一个原型范围的bean不会在bean列表中表示,因为它们是原型范围的。


@AllArgsConstructor

@Service

public class ServiceClass {


    private final ObjectProvider<ProtoTypeBean> provider;


    public void demoMethod(ArrayList<String> someArrayList) {

        PrototypeBean pb = provider.getIfUnique();

        for(var singleString: someArrayList) {

            pb.setFieldValue(singleString);

            pb.add(prototypeBean);              

        }

        System.out.println(prototypeBean.toString());

    }

}

另外,如果您不需要所有依赖注入,代理创建等来为您的对象提供服务,那么为什么要打扰。在Spring应用程序中仅使用关键字没有错。并非所有事情都必须由Spring管理。new


查看完整回答
反对 回复 2022-08-03
?
慕尼黑8549860

TA贡献1818条经验 获得超11个赞

设置您的原型 Bean,如下所示:


@Getter

@Setter

@Component

@Scope("prototype")

public class ProtoTypeBean {


  final private String param;


  public ProtoTypeBean(final String p) {

    this.param = p;

  }

}

现在,在您的服务类中使用BeanFactory为您创建Bean:


@Service

@AllArgsConstructor

public class ServiceClass {


  private final BeanFactory factory;

  private List<ProtoTypeBean> prototypeBeans;


  @Autowired

  public ServiceClass(final BeanFactory f) {

    this.factory = f;

  }


  public void demoMethod(List<String> someArrayList) {


    this.prototypeBeans = someArrayList

        .stream()

        .map(param -> factory.getBean(ProtoTypeBean.class, param))

        .collect(Collectors.toList());

  }

}


查看完整回答
反对 回复 2022-08-03
?
浮云间

TA贡献1829条经验 获得超4个赞

我最近遇到了这个问题。我相信一定有比我更好的方法,但这就是我的做法:


public class ServiceClass {


ArrayList<ProtoTypeBean> prototypeBeans = new ArrayList<>();


@Autowired

ApplicationContext ctx;


public void demoMethod(ArrayList<String> someArrayList) {

    for(var singleString: someArrayList) {

        //magic is in below line.. getting a bean from ApplicatioContext.

        ProtoTypeBean prototypeBean= ctx.getBean("protoTypeBean"); //Or ctx.getBean(ProtoTypeBean.class);

        prototypeBean.setFieldValue(qBean.getFieldValue());


        prototypeBeans.add(prototypeBean);              

    }

    System.out.println(prototypeBeans.toString());

}

这样,Spring容器始终会为您提供一个新实例。它完全由Spring容器管理。


您尝试的方式,我也尝试过,但它总是会在自动布线时注入一个实例,从而破坏了原型设计的目的。


你可以走使用关键字的路线。但是,这只是常规的Java实例化,我认为Spring不会管理新实例,因为它的注释不是.不过,我在这里可能是错的。new@Component@Configuration


查看完整回答
反对 回复 2022-08-03
  • 3 回答
  • 0 关注
  • 97 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信