在Spring中允许并发的正确Bean的proxyMode是什么?

时间:2018-04-20 20:17:03

标签: java spring inversion-of-control

我正在构建一个基于Spring Framework的库,我希望允许用户并行调用Library的方法。

在我的主要班级中,我自动装备服务类:

@Autowired
private ExportListCommand exportList;

这是图书馆方法的实施:

public ResponseContainer<ExportListResponse> exportList(ExportListOptions options) {
    exportList.setoAuthClient(oAuthClient);
    ResponseContainer<ExportListResponse> result = exportList.executeCommand(options);

    return result;
}

ExportListCommand被定义为Bean:

@Bean
@Scope("prototype")
public ExportListCommand exportList() {
    return new ExportListCommand();
}

当我作为一个库用户并行运行2个exportList的方法时,Spring只创建一个ExportListCommand bean,因为它只自动装配一次。但实际上我需要2个独立的ExportListCommand bean。我还尝试将@Scope(value="prototype")更改为@Scope(value="prototype", proxyMode=ScopedProxyMode.TARGET_CLASS),但这也不能正常工作:Spring为每个方法调用创建ExportListCommand bean,因为我失去了oAuthClient值得到新的对象。

我只使用了AnnotationConfigApplicationContext.getBean()方法,我希望避免这种做法。

我的选择是什么?感谢。

1 个答案:

答案 0 :(得分:0)

我相信你正在寻找一家工厂&#39;对象

从Spring的角度来看,我有两种主要方法可以考虑这个问题。

  1. &#39; Java&#39;方式:创建一个将返回ExportListCommand
  2. 实例的工厂对象

    这个工厂看起来像这样:

    class ExportListCommandFactory {
        ExportListCommand newInstance() {
            return new ExportListCommand();
        }
    }
    

    并将在您的方法中使用,如下所示:

    @Autowire
    private ExportListCommandFactory commandFactory;
    
    public ResponseContainer<ExportListResponse> exportList(ExportListOptions options) {
        final ExportListCommand exportList = commandFactory.newInstance();
        exportList.setoAuthClient(oAuthClient);
        ResponseContainer<ExportListResponse> result = exportList.executeCommand(options);
    
        return result;
    }
    

    当然,执行此操作需要您更改配置以包含ExportListCommandFactory而不是ExportListCommand的bean。

    或者,您可以考虑......

    1. 春天&#39;方式:使用FactoryBean
    2. 您需要在这里做的唯一事情是,在您的主要课程中@Autowire FactoryBean<ExportListCommand>而不是ExportListCommand,并在您需要调用方法的方法中,请咨询工厂以获取您的实例。

      @Autowire
      private FactoryBean<ExportListCommand> commandFactory;
      
      public ResponseContainer<ExportListResponse> exportList(ExportListOptions options) {
          final ExportListCommand exportList = commandFactory.getObject();
          exportList.setoAuthClient(oAuthClient);
          ResponseContainer<ExportListResponse> result = exportList.executeCommand(options);
      
          return result;
      }
      

      您不需要更改配置,因为FactoryBean是一个特殊的bean,它会在每次调用getObject()时查询实例的ApplicationContext / BeanFactory。