如果相同的业务逻辑适用于两个帐户,但考虑到您不能让单个服务类与两个帐户的 API 对话,那么是的,您可以使用 2 个服务类(只不过是 2 个不同的 spring bean)默认单例范围。
class Account1Service{
}
class Account2Service{
}
如果我有可以共享的通用逻辑,我也会尝试在这种情况下是否可以在这里使用继承。但请记住,如果您从抽象类继承服务类,则必须将抽象类放置在src/groovy
外部/grails-app/
,以对抗依赖注入。在这种情况下,您最终可能会得到(未经测试,但您可以坚持 DRY 概念)
// src/groovy
abstract class BrokerageService {
def populateAccountDetails(Long accountId)
def checkAccountStatus(Long accountId)
}
//grails-app/services
class Account1Service extends BrokerageService {
//Implement methods + add logic particular to Account1
//By default transacitonal
}
class Account2Service extends BrokerageService {
//Implement methods + add logic particular to Account2
//By default transacitonal
}
还要注意范围是singleton
,您会格外小心(最好避免)维护 Service 类中的全局范围属性。尽量做到无状态。除非情况或业务逻辑要求使用 , 或 等服务级别范围session
,flow
否则request
我将始终坚持使用默认singleton
范围。
要回答您的第二个问题,您不需要实例化任何 grails 服务类。当使用适当的命名法时,容器会注入适当的服务类(使用 Spring IoC)。在上面的示例中,如果您在要使用服务的类中遵循此命名约定,则会自动注入服务类:
//camelCase lower initial
def account1Service
def account2Service
更新
这是对 OP 提供的附加信息的回应。
参考上述场景,默认范围内只能有一个service
类可以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
}
}
服务类的范围是单例的,这意味着堆中只有一个类的实例,这也意味着任何类级别的属性(方法除外)都是有状态的。在这种情况下,您只处理无状态且足以满足目的的方法。您将获得所需的东西,而无需花费堆或BrokerageService
每次交易发生时都创建新实例。
每笔交易(关联账户)最终都会调用服务,从 db(或配置属性、平面文件或属性文件)中查找凭证,然后配置 IB 网关并调用/与网关通话。