猿问

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

我有一个用原型范围定义的组件。我想在我的服务类中使用该组件。我希望春天每次我呼唤它时都能为我提供一个新的豆子实例。


组件类:


@Getter

@Setter

@Component

@Scope("prototype")

public class ProtoTypeBean {

  //.. Field variables

}

服务等级:


@AllArgsConstructor

@Service

public 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 的新实例,但我也听说这是一个不好的做法。因此,请帮助我进行最佳实践。


扬帆大鱼
浏览 98回答 3
3回答

潇潇雨雨

使用 ObjectProvider 懒洋洋地获得所需的结果。然而,第一个原型范围的bean不会在bean列表中表示,因为它们是原型范围的。@AllArgsConstructor@Servicepublic class ServiceClass {&nbsp; &nbsp; private final ObjectProvider<ProtoTypeBean> provider;&nbsp; &nbsp; public void demoMethod(ArrayList<String> someArrayList) {&nbsp; &nbsp; &nbsp; &nbsp; PrototypeBean pb = provider.getIfUnique();&nbsp; &nbsp; &nbsp; &nbsp; for(var singleString: someArrayList) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pb.setFieldValue(singleString);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pb.add(prototypeBean);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; System.out.println(prototypeBean.toString());&nbsp; &nbsp; }}另外,如果您不需要所有依赖注入,代理创建等来为您的对象提供服务,那么为什么要打扰。在Spring应用程序中仅使用关键字没有错。并非所有事情都必须由Spring管理。new

慕尼黑8549860

设置您的原型 Bean,如下所示:@Getter@Setter@Component@Scope("prototype")public class ProtoTypeBean {&nbsp; final private String param;&nbsp; public ProtoTypeBean(final String p) {&nbsp; &nbsp; this.param = p;&nbsp; }}现在,在您的服务类中使用BeanFactory为您创建Bean:@Service@AllArgsConstructorpublic class ServiceClass {&nbsp; private final BeanFactory factory;&nbsp; private List<ProtoTypeBean> prototypeBeans;&nbsp; @Autowired&nbsp; public ServiceClass(final BeanFactory f) {&nbsp; &nbsp; this.factory = f;&nbsp; }&nbsp; public void demoMethod(List<String> someArrayList) {&nbsp; &nbsp; this.prototypeBeans = someArrayList&nbsp; &nbsp; &nbsp; &nbsp; .stream()&nbsp; &nbsp; &nbsp; &nbsp; .map(param -> factory.getBean(ProtoTypeBean.class, param))&nbsp; &nbsp; &nbsp; &nbsp; .collect(Collectors.toList());&nbsp; }}

浮云间

我最近遇到了这个问题。我相信一定有比我更好的方法,但这就是我的做法:public class ServiceClass {ArrayList<ProtoTypeBean> prototypeBeans = new ArrayList<>();@AutowiredApplicationContext ctx;public void demoMethod(ArrayList<String> someArrayList) {&nbsp; &nbsp; for(var singleString: someArrayList) {&nbsp; &nbsp; &nbsp; &nbsp; //magic is in below line.. getting a bean from ApplicatioContext.&nbsp; &nbsp; &nbsp; &nbsp; ProtoTypeBean prototypeBean= ctx.getBean("protoTypeBean"); //Or ctx.getBean(ProtoTypeBean.class);&nbsp; &nbsp; &nbsp; &nbsp; prototypeBean.setFieldValue(qBean.getFieldValue());&nbsp; &nbsp; &nbsp; &nbsp; prototypeBeans.add(prototypeBean);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; }&nbsp; &nbsp; System.out.println(prototypeBeans.toString());}这样,Spring容器始终会为您提供一个新实例。它完全由Spring容器管理。您尝试的方式,我也尝试过,但它总是会在自动布线时注入一个实例,从而破坏了原型设计的目的。你可以走使用关键字的路线。但是,这只是常规的Java实例化,我认为Spring不会管理新实例,因为它的注释不是.不过,我在这里可能是错的。new@Component@Configuration
随时随地看视频慕课网APP

相关分类

Java
我要回答