Как динамически выбирать услугу в Grails

Из моего контроллера я хотел бы динамически выбирать услугу на основе параметра.

В настоящее время у меня есть базовая услуга и некоторые другие сервисы, которые обеспечивают эту базовую услугу. На основе параметра я вызываю класс, который создает имя bean на основе параметра и в конечном итоге вызывает следующее:

import org.codehaus.groovy.grails.web.context.ServletContextHolder as SCH
import org.codehaus.groovy.grails.web.servlet.GrailsApplicationAttributes as GA

class Resolver {
    def ctx

def getBean(String beanName) {
    if(!ctx) {
        ctx = SCH.servletContext.getAttribute(GA.APPLICATION_CONTEXT)
    }
    return ctx."${beanName}"
}

}

Это возвращает службу, которую я хочу. Однако я чувствую себя довольно грязно, делая это таким образом. У кого-нибудь есть лучший способ справиться с получением услуги (или любого другого bean) на основе некоторого параметра?

Спасибо.

Ответ 1

ctx."${beanName}" добавляется к метаклассу ApplicationContext, поэтому вы можете делать такие вещи, как def userService = ctx.userService. Это просто ярлык для ctx.getBean('userService'), чтобы вы могли изменить свой код на

return ctx.getBean(beanName)

и это будет одно и то же, но менее волшебное.

Поскольку вы вызываете это из контроллера или службы, я пропускаю материал ServletContextHolder и получаю контекст из-за зависимости, вставляя grailsApplication bean (def grailsApplication) и получая его через def ctx = grailsApplication.mainContext. Затем передайте его в этот вспомогательный класс (помните, что большая парадигма Spring - это инъекция зависимостей, а не старая школьная зависимость), и тогда это будет просто

class Resolver {
   def getBean(ctx, String beanName) {
      ctx.getBean(beanName)
   }
}

Но тогда это так просто, что я бы не стал беспокоиться о вспомогательном классе:)