ここで読んだように、grails は methodMissing を使用して GORM メソッドをドメイン クラスに注入していますが、methodMissing は実行コストが高く、ディスパッチが失敗した場合にのみ発生すると言いましたが、なぜこれらのメソッドは metaClass または AST 変換を介して注入されないのですか? 手がかりはありますか?
2 に答える
methodMissing の使用はそれほど高価ではありません。Grails は、見つからないメソッドの最初の実行時にのみ MOP に新しいメソッドを作成するからです。その後の実行は、新しく作成されたメソッドで行われます。
多くのプロパティを持つドメイン クラスを考えてみましょう。すべての findBy*、findAllLBy*、countBy* などの順列をコンパイル時に作成する必要がある場合、クラスは簡単に非常に大きくなる可能性があります。メソッド eMissing を使用すると、実行時に実際に使用されるメソッドのみが作成されます。
コードを理解しているので、この情報は古くなっています。これらのメソッドはメタクラスに注入されます。grails-hiberante プラグインのコードを見てください。
HibernateGrailsPlugin.groovy
( github ) 行 49 は、コンテキストが開始されるたびに実行されます。
def doWithDynamicMethods = HibernatePluginSupport.doWithDynamicMethods
HibernatePluginSupport
次に、 (github )を開き、フローに従います。
/*451*/ static final doWithDynamicMethods = { ApplicationContext ctx ->
def grailsApplication = application
enhanceSessionFactories(ctx, grailsApplication)
}
/*456*/ static void enhanceSessionFactories(ApplicationContext ctx, grailsApplication, source = null)
// calls in line 464:
/*464* enhanceSessionFactory sessionFactory, grailsApplication, ctx, suffix, datastores, source
このクロージャーは、enhanceSessionFactory
メソッド内で重要です。
/*548*/ def enhanceEntity = ...
そして、581 行目から 583 行目ですべてのエンティティに対して呼び出されます。method の 587 行目からメソッドが生成されregisterNamespaceMethods
ます。そして、私が正しく理解しているように、これらのメソッドは 597 行目から直接 metaClass に注入されます。
def classLoader = application.classLoader
def finders = HibernateGormEnhancer.createPersistentMethods(application, classLoader, datastore)
def staticApi = new HibernateGormStaticApi(dc.clazz, datastore, finders, classLoader, transactionManager)
dc.metaClass.static."$getter" = { -> staticApi }
def validateApi = new HibernateGormValidationApi(dc.clazz, datastore, classLoader)
def instanceApi = new HibernateGormInstanceApi(dc.clazz, datastore, classLoader)
dc.metaClass."$getter" = { -> new InstanceProxy(delegate, instanceApi, validateApi) }
私が間違っている場合は、修正して修正してください。すべてが正しいという自信はありません。これらは、Grails のソース コードを読んでいるときに見つけたものにすぎません。