2016-03-30 7 views
0

私はCustomServiceを含む新しいプラグインを作成しています。このプラグインは、既存のプラグインから既存のサービスを置き換えることを意図しています。カスタムセキュリティ実装のパターンに従って、hereと表示されたら、resources.groovyのoldService(path.to.new.CustomService)に設定を追加しました。私はまた、注入されたすべてのクラスをこのサービスのクロージャに追加しようとしました。 (実際のサービス名は、コードブロックのRegistrationPersonRegistrationCompositeServiceとNewRegistrationPersonRegistrationCompositeServiceです)Spring Bean宣言を使用してGrailsでサービスをオーバーライド

私は元のアプリケーションコードに新しいプラグインへの参照を欲しません。ただし、アプリケーションレベルのBuildConfigにはplugin.locationエントリが必要です。私のresource.groovy改造は新しいプラグインにあります。私はこの試みに成功していません。間違ったリソースを修正していますか?元のアプリケーションコードでこの変更が必要な場合は、元のコードを変更せずにそのまま残すことができません。私はオリジナルのサービスを拡張したり、オーバーライドアノテーションを使用しているわけではありません。私の意図は、起動時にサービス(Spring Bean)を置き換えることです。新しいプラグインは、これらのクラスをロードする際の操作の順序を管理するために、古いプラグインに依存しています。

古いサービスが以前にコントローラに挿入されていることは重要ですか?これは同じ方法で新しいプラグインのコントローラーをオーバーライドし、必要な動作のための正しいサービスを注入する必要がありますか?

プラグイン内でresources.groovyが無視されることを示すドキュメントが見つかりました。また、resources.groovyを戦争に組み込むことは問題である。私は解決策を見出していない。私は、共有することができます、希望の動作が欠落しているというエラーは表示されません。元のサービスが要求を処理しています。

//was resource.groovy - now renamed to serviceOverRide.groovy - still located in \grails-app\conf\spring of plugin 
//tried this with and without the BeanBuilder. Theory: I'm missing the autowire somehow 
import org.springframework.context.ApplicationContext 
import grails.spring.BeanBuilder 

def bb = new BeanBuilder() 

bb.beans { 
    registrationPersonRegistrationCompositeService(path.to.services.registration.NewRegistrationPersonRegistrationCompositeService) { bean -> 
     bean.autowire = true 
     registrationRestrictionCompositeService = ref("registrationRestrictionCompositeService") 
     registrationPersonTermVerificationService = ref("registrationPersonTermVerificationService") 
    } 
    classRegistrationController(path.to.services.registration.ClassRegistrationController) { bean -> 
     bean.autowire = true 
     selfServiceLookupService = ref("selfServiceLookupService") 
     registrationPersonRegistrationCompositeService = ref("registrationPersonRegistrationCompositeService") 
    } 
} 
ApplicationContext appContext = bb.createApplicationContext() 

追加情報:PluginGrailsPlugin.groovyに次の行を追加しました。元のサービスは、まだ私は非常にあなたがPluginsのドキュメントのセクションを読むことをお勧めします

def dependsOn = ['appPersonRegistration': '1.0.20 > *'] 
List loadAfter = ['appPersonRegistration'] 

def doWithSpring = { 
    registrationPersonCourseRegistrationCompositeService(path.to.new.registration.TccRegistrationPersonCourseRegistrationCompositeService) 
} 

def doWithApplicationContext = { applicationContext -> 
    SecurityContextHolder.setStrategyName(SecurityContextHolder.MODE_INHERITABLETHREADLOCAL) 
    DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) applicationContext.getBeanFactory() 
    beanFactory.registerBeanDefinition("registrationPersonCourseRegistrationCompositeService", BeanDefinitionBuilder.rootBeanDefinition(TccRegistrationPersonCourseRegistrationCompositeService.class.getName()).getBeanDefinition()) 
} 

答えて

1

これらの要求を処理しています。私はこれをお勧めする理由理由は、プラグイン:

  • には、またはresources.groovy
  • の使用では、ドキュメント内の情報に続いて春のアプリケーション

を達成するためにdoWithSpringを通じて手段を提供しないでくださいアプリケーションのコンテキストでサービスをオーバーライドする必要はありません。

doWithSpringを使用してアプリケーションコンテキストへの変更を実装する必要があります。これが問題を解決する鍵です。

+0

doWithAplicationContextは、このソリューションの一部です。それでもBeanを読み込むことに失敗しましたが、根本的な原因は、Bean自体が他の登録/注入されたBeanに依存しているようです。resources.groovy/beans宣言と、この宣言に適用Beanをリンクするクロージャを使用した例://stackoverflow.com/questions/7132679/override-method-of-grails-plugin-bean/7135267#7135267 SpringSecurity beanとその注入されたbean。私の挑戦は、BeanFactoryとdoWithApplicationContextで同様に行うことです。ネストされた豆を利用してこの問題や解決策を見ましたか? – Duane5000

0

この実装では、オーバーライドを提供しようとしていたサービスにユーティリティメソッドがありました。問題は、Aspectはプロキシとして機能し、別のクラスから直接呼び出されるメソッドをオーバーライドする必要があることです。私のclassRegistrationControllerでは、serviceRegistration()というサービスを呼び出していましたが、これが順番にapplyRules()と呼ばれていました。使用される例のみのメソッド名。サービスが独自のユーティリティを呼び出すため、プロキシ/ラッパーがapplyRules()の呼び出しを回避する機会はありませんでした。これが発見されると、私はこのようにしてコードをリファクタリングしました。コントローラーは常にprocessRegistrationを呼び出します。返された後、サービスprocessLocalRules()に別の呼び出しが行われます。新しいメソッドは、クライアントのカスタムロジックによってオーバーライドされることを意図した空のプレースホルダです。 Aspectのプラグインはresources.groovyを使って動作します。Joshuaが説明したように私はdoWithSpringを好む:元のapp-configを変更せずにプラグインを動作させる私の意図。そうでなければ、resource.groovyは有効なアプローチです。ジョシュアの答えをアップアップすることは、要件を満たし、よりクリーンであるためです。ありがとう!

関連する問題