我想通过安装插件来覆盖服务实现 - 安装插件时我希望使用该插件版本的服务,并且在卸载插件时我希望使用默认版本的服务
为了防止浪费时间,我将使用代码解释我的问题。我有一个“常见插件”,由我的主应用程序和我的“自定义插件”共享,具有以下内容:
public interface SimpleService {
void doProcessing();
}
然后我有一个包含以下
的“主要应用程序”服务接口的默认实现:
public DefaultSimpleService implements SimpleService {
void doProcessing() {
// ...
}
resource.groovy:
simpleService(DefaultSimpleService) { bean ->
bean.autowire = 'byName'
}
使用该服务的控制器:
class SimpleController {
def simpleService
def index() {
simpleService.doProcessing()
}
}
到目前为止一切顺利。我现在想做的是通过安装一个插件来替换SimpleService
接口的实现。我不想在我的应用程序中更改任何配置。
我有一个带有新服务实现的插件:
public CustomSimpleService implements SimpleService {
void doProcessing() {
// ...
}
}
我的第一次尝试是在插件“doWithSpring”部分注册自定义服务bean,但它总是被主应用程序覆盖。很公平,因为看起来插件总是在主应用程序bean注册之前加载(?)
我的第二次尝试是在CustomServiceGrailsPlugin.groovy中的“doWithApplicationContext”中注册自定义bean:
def doWithApplicationContext = { applicationContext ->
DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) applicationContext.getBeanFactory()
beanFactory.registerBeanDefinition("simpleService", BeanDefinitionBuilder.rootBeanDefinition(CustomSimpleService.class.getName()).getBeanDefinition())
}
这实际上是部分工作 - 当加载插件时,使用SimpleService的插件实现,如果卸载了插件,则使用SimpleService
的主应用程序实现。但是有一个方面的问题:bean的自动装配在“手动”注册的插件实现中不起作用......
然后我开始看BeanPostProcessors
,但从我看到的内容看起来似乎无法解决我的问题。
那么如何解决我的问题?
此致 Tobbe
答案 0 :(得分:2)
我认为最好的办法是检查插件是否已安装,如果是,请不要在应用程序中声明服务。
您可以查看安装的插件:org.codehaus.groovy.grails.plugins.PluginManagerHolder.pluginManager.allPlugins
您可以在resources.groovy
中使用它boolean containsPlugin(String pluginName) {
def names = org.codehaus.groovy.grails.plugins.PluginManagerHolder.pluginManager.allPlugins.collect { it -> return it.name }
return(pluginName in names)
}
beans = {
if(!containsPlugin("thePlugin")) {
println "Installation not contains plugin, defining bean!"
myService(...)
}
}