Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/grails/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Grails 如何创建同一服务的两个已配置实例?_Grails - Fatal编程技术网

Grails 如何创建同一服务的两个已配置实例?

Grails 如何创建同一服务的两个已配置实例?,grails,Grails,我有一个与经纪账户API交互的服务。它工作正常,但现在我需要与同一经纪公司的两个不同帐户进行交互 处理这一问题的最佳方法似乎是将服务配置为指定目标帐户,然后实例化两个不同的实例,每个帐户一个 我不确定Grails是否支持这一点,也不知道如何实现这一点 两个问题: 有更好的方法吗 如果没有,我如何实例化和配置两个不同的服务实例 其他信息: 这两个答案都差一点。我想澄清一下: 我不想谈细节,但这可能有助于解释我所追求的。我使用的是交互式经纪人交易API,他们不允许你像其他经纪人那样直接与他们的服务器

我有一个与经纪账户API交互的服务。它工作正常,但现在我需要与同一经纪公司的两个不同帐户进行交互

处理这一问题的最佳方法似乎是将服务配置为指定目标帐户,然后实例化两个不同的实例,每个帐户一个

我不确定Grails是否支持这一点,也不知道如何实现这一点

两个问题:

  • 有更好的方法吗
  • 如果没有,我如何实例化和配置两个不同的服务实例
  • 其他信息:

    这两个答案都差一点。我想澄清一下:

    我不想谈细节,但这可能有助于解释我所追求的。我使用的是交互式经纪人交易API,他们不允许你像其他经纪人那样直接与他们的服务器对话。您必须通过一个套接字与他们的IB网关通信,这是他们提供的一个软件,基本上是代理他们的服务器。因此,您的应用程序与IB Gateway对话,IB Gateway代表您的应用程序与交互式代理服务器对话

    问题是IB网关必须登录到帐户,作为其配置的一部分。因此,为了交易两个不同的帐户,您别无选择,只能配置两个不同的IB网关,因为每个网关只能访问为其配置的帐户

    因此,我的Grails交易代码必须选择正确的IB网关进行对话。这意味着它需要知道与每个帐户对应的IB网关的IP地址和端口。除了此IP地址和端口设置之外,与IB网关通信的两个Grails服务之间没有区别

    我想要的是重用相同的服务类,每个服务类都被实例化为一个单例,只是有一个不同的IP地址和通信端口

    因此,创建两个不同的服务是不可取的,因为代码在其他方面是相同的。(如果我添加第三个或第四个IB网关,这将成为相当难闻的代码。)

    这个设置应该在应用程序的生命周期内存在,所以我认为范围的改变也不是真正的答案

    我真的希望有两个相同服务的实例,只是配置不同而已


    我希望这有助于解释这种情况。你有什么建议?谢谢大家!

    Grails服务应该是这样的,没有任何与它正在做的事情相关联的状态,通常只有一个实例。也就是说,通常情况下,它们中不会有实例字段

    但如果覆盖默认范围,则可以使用它们。例如,您可以将服务设置为会话范围,添加以下静态变量:

    static scope = "session"
    
    然后,每个用户会话将有一个实例

    对于您的特定情况,您可能希望查看prototype范围,它将在每次需要注入服务时为您提供一个新的服务实例。如果您希望实例对相同的数据起作用,您只需确保在注入实例后始终使用该实例


    看看。

    如果相同的业务逻辑适用于两个帐户,但考虑到不能有一个服务类与两个帐户的API进行通信,那么可以有两个服务类(只不过是两个不同的SpringBean)和默认的singleton作用域

    class Account1Service{
    }
    
    class Account2Service{
    }
    
    我也会尝试在这种情况下是否可以使用继承,如果我有可以跨平台共享的公共逻辑。但是请记住,如果您是从抽象类继承服务类,那么抽象类必须放在
    src/groovy
    中,也就是说,放在
    /grails-app/
    之外,以抵抗依赖注入。在这种情况下,您可能会得到(未经测试,但您可以坚持干燥的概念)

    还要注意,作用域是单例的,您需要特别注意(最好避免)在服务类中维护全局作用域属性。尽量使其成为无状态。除非情况或业务逻辑要求使用服务级别范围,如
    会话
    请求
    ,否则我将始终坚持默认的
    单例
    范围

    要回答第二个问题,不需要实例化任何grails服务类。当使用适当的术语时,容器注入适当的服务类(使用Spring IoC)。在上面的示例中,如果在要使用服务的类中遵循此命名约定,则服务类将自动注入:

    //camelCase lower initial
    def account1Service 
    def account2Service
    
    更新
    这是对OP提供的附加信息的回应

    参考上述场景,在默认的
    singleton
    范围中只能有一个
    service
    类来完美地处理事情。最好的一点是,由于您正在脱离您的网络,并且并不真正担心自己的数据库事务,所以可以将服务类设置为非事务性。但这也要视情况而定。下面是服务类的外观

    //grails-app/service
    class BrokerageService{
    
        //Service method to be called from controller or any endpoint
        def callServiceMethod(Long accountId){
            .......
            doSomethingCommonToAllAccounts()
            .........
    
            def _ibConfig = [:] << lookupIBGatewayConfigForAccount(accountId)
            ........
    
            //Configure an IB Gateway according to the credentials
            //Call IB Gateway for Account using data got from _ibConfig map
            //Call goes here 
        }
    
        def doSomethingCommonToAllAccounts(){
            ........
            ........
        }
    
        def lookupIBGatewayConfigForAccount(accountId){
            def configMap = [:]
            //Here lookup the required IP, account credentials for the provided account
            //If required lookup from database, if you think the list of accounts would grow
            //For example, if account is JPMorgan, get credentials related to JPMorgan
    
            //put everything in map
            configMap << [ip: "xxx.xx.xx.xxx", port: 80, userName: "Dummy"] //etc
    
            return configMap
        }
    }
    
    //grails应用程序/服务
    类别经纪服务{
    //要从控制器或任何端点调用的服务方法
    def callServiceMethod(长帐户ID){
    .......
    DOSOMEthingCommmontalAccounts()
    .........
    
    def_ibConfig=[:]当你说服务时,你是指Grails服务吗?为什么你觉得这是为每个帐户创建新的服务类实例的最好方法,而不是使用默认的
    singleton
    范围?是的,是Grails服务。我不确定你的意思。我希望每个服务都是一个singleton,运行相同的代码,但有一个实例包含帐号的eld。您是否建议相同的singleton服务处理两个帐户的订单?如果是,则不会
    //grails-app/service
    class BrokerageService{
    
        //Service method to be called from controller or any endpoint
        def callServiceMethod(Long accountId){
            .......
            doSomethingCommonToAllAccounts()
            .........
    
            def _ibConfig = [:] << lookupIBGatewayConfigForAccount(accountId)
            ........
    
            //Configure an IB Gateway according to the credentials
            //Call IB Gateway for Account using data got from _ibConfig map
            //Call goes here 
        }
    
        def doSomethingCommonToAllAccounts(){
            ........
            ........
        }
    
        def lookupIBGatewayConfigForAccount(accountId){
            def configMap = [:]
            //Here lookup the required IP, account credentials for the provided account
            //If required lookup from database, if you think the list of accounts would grow
            //For example, if account is JPMorgan, get credentials related to JPMorgan
    
            //put everything in map
            configMap << [ip: "xxx.xx.xx.xxx", port: 80, userName: "Dummy"] //etc
    
            return configMap
        }
    }