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