3

プラグインをインストールするだけでサービスの実装をオーバーライドしたい-プラグインがインストールされているときはサービスのプラグインバージョンを使用し、プラグインがアンインストールされているときはサービスのデフォルトバージョンを使用したい。

時間を無駄にしないために、コードを使用して問題を説明します。メインアプリケーションと「カスタムプラグイン」で共有される「共通プラグイン」があります。

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が登録される前にプラグインが常にロードされるように見えるので、十分に公平です(?)

2番目の試みは、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しかし私が読んだものからそれは私の問題を解決しないように見えました。

では、どうすれば問題を解決できますか?

よろしくトッベ

4

1 に答える 1

3

プラグインがインストールされているかどうかを確認し、インストールされている場合はアプリケーションでサービスを宣言しないのが最善の策だと思います。

インストールされているプラ​​グインを確認できます。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(...)
  }
}
于 2013-02-25T18:18:06.617 に答える