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

如何在没有applicationContext的情况下请求Spring服务类中的原型bean

姬正文
2023-03-14

我有一个用原型范围定义的组件。我想在我的服务类中使用该组件。我希望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());
    }
}

通过使用这个配置,我在我的prototypeBeans ArrayList中获得了相同的ProtoTypeBean实例。问题是,当我每次在foreach循环中调用它时,我如何让Spring理解给我一个prototypeBean的新实例?我发现我可以使用ApplicationContext.getBean()在foreach循环中获得Bean的新实例,但我也听说这是一种不好的做法。所以请帮助我实现最佳实践。

共有3个答案

单于旭东
2023-03-14

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

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容器管理。

你尝试的方式,我也尝试过,但它总是在自动装配时注入一个实例,因此违背了原型设计的目的。

您可以使用<code>new<code>关键字。但这只是常规的Java实例化,我认为新实例不是由Spring管理的,因为它是用<code>组件

储嘉悦
2023-03-14

设置您的原型bean类似于:

@Getter
@Setter
@Component
@Scope("prototype")
public class ProtoTypeBean {

  final private String param;

  public ProtoTypeBean(final String p) {
    this.param = p;
  }
}

现在,在您的服务类中使用< code>BeanFactory为您创建beans:

@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());
  }
}
夏弘文
2023-03-14

使用对象提供程序懒洋洋地获取所需的结果。然而,第一个原型范围的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管理。

 类似资料:
  • 有没有办法在Spring MVC中获取当前会话,但不是通过请求。通常,我们所做的是在操作/控制器类方法中获取请求。从这个请求中,我们逐个请求获得会话。getSession()。但是,有没有办法在没有此请求对象的情况下获取此会话? 我的动机是,在一个实用程序类中,我需要访问会话中设置的值,而这个实用程序类方法是从控制器类的50多个方法中访问的。如果我必须从请求中获得会话,那么我需要更改所有这50个位

  • 问题内容: 是否有可用的Tomcat API或配置可以告诉应用程序(可能在启动时)在没有请求的情况下在哪个端口上运行? 想象一个场景,其中有两个Web应用程序在同一个Tomcat中运行,并且其中一个需要从另一个中调用Web服务。我们不希望该请求离开Tomcat(如果您使用Apache服务器名称或绝对URL,则该请求将发出并再次返回,并且可以转到任何实例)并再次进入。为此,我知道机器名称,但无法获取

  • 我有一个Spring boot项目,它有使用kafka进行日志记录的依赖项。我无法摆脱所述依赖项,因为我的逻辑需要来自该依赖项的代码 我已尝试禁用自动配置 我尝试通过bean配置将missingTopicsFatal设置为false 但很明显,设置已经是假的,因为我的应用程序运行时没有失败,只是tomcat不想打开侦听端口 应用程序启动,但spring拒绝打开侦听端口,并继续使用错误进行循环 在本

  • 问题内容: 我正在尝试设置spring xml配置,而不必创建进一步的。但是,即使我将数据库属性包括在 spring.xml: 我在这里想念什么? 问题答案: 在entityManagerFactory bean定义中指定“ packagesToScan”和“ persistenceUnitName”属性。 请注意,这适用于Spring版本> 3.1

  • 问题内容: 我想问一下我是否可以在没有安装Web服务器的情况下运行php。我是否必须像CGI一样使用php并通过命令行运行我的页面?如果是这样,我必须通过安装php选择哪些步骤?我是说偏好设置为CGI以及该步骤之后的组件? 我安装了php 5.3.3,但似乎无法正常工作,我收到几则消息,提示缺少php5ts.dll,当我将该文件放在ext文件夹中时,会出现其他错误消息。是否需要使用任何配置文件或步