我试图在构造函数中为另一个服务注入服务依赖项。(参见下面的示例代码)。但是,当我尝试分配api变量时,即使正确设置了bean变量,也会抛出NoSuchBeanDefinitionException。
值得一提的是,当我扩展此服务并初始化子服务时会发生这种情况。
我的问题是,我怎样才能根据Config.groovy中的设置正确地将依赖服务注入我的班级?
class MyService {
def api
public MyService() {
def beanString = ConfigurationHolder.config.api
def bean = ApplicationHolder.application.getMainContext().getBean(GrailsNameUtils.getPropertyName(beanString))
this.api = bean
}
}
编辑:澄清我的想法。我有两个API:一个XML和一个JSON,它们提供相同的数据,但具有不同的表示形式。但是,我希望能够在配置文件中设置api,例如带有api-name的字符串。
我的想法是为可用的api(ApiInterface)建立一个通用接口,然后当我初始化使用api的服务时,将实例变量设置为配置的api。
除此之外,我希望能够具有特定于服务的设置,即在配置文件中注入api的每个服务的设置,该配置文件设置使用哪个api。 例如
Config.groovy
firstService { api = "xml" } secondService { api = "json" }
答案 0 :(得分:0)
没有太多信息可以继续。是否在创建MyService时创建了config.api属性中定义的bean?你是如何保证的?
我认为你可以做一些懒惰的初始化来解决它:
class MyService {
static class ApiBeanHolder {
static api = ApplicationHolder.application.getMainContext().getBean(GrailsNameUtils.getPropertyName(ConfigurationHolder.config.api))
}
def doSomeWork = {
def bean = ApiBeanHolder.api
bean.callBeanMethod
}
}
未经测试,并且不知道它是否能解决您的特定问题。
答案 1 :(得分:0)
我怀疑你可以毫不费力地使用它,因为实例是由Spring在构建bean时创建的,所以另一个bean可能还没有。你可以在第一次请求时懒洋洋地查看它:
class MyService {
def grailsApplication
private apiBean // use different name so 'api' resolves as property to getApi()
def someMethod() {
def foo = api.someMethodCall()
...
}
def someOtherMethod() {
def bar = api.someOtherMethodCall()
...
}
private getApi() {
if (apiBean == null) {
String beanString = grailsApplication.configuration.api
apiBean = grailsApplication.mainContext.getBean(
GrailsNameUtils.getPropertyName(beanString))
}
apiBean
}
}