2012-12-04 32 views
2

當我讀here時,grails使用methodMissing將GORM方法注入到域類中,但是說methodMissing執行起來很昂貴,只有在調度失敗的情況下才會發生,爲什麼這些方法不是通過metaClass或AST Transformations注入?任何線索?爲什麼GORM使用methodMissing

+2

從Grails 2開始,大多數方法都是使用AST添加的。動態方法(findBy *,findAllBy *等)並不是因爲@sbglasius指出最好添加那些點播 –

+0

好吧,所以據我瞭解sbglasius和Tomasz都是正確的,不是嗎?我的意思是Tomasz指出有些方法是由AST添加的,但由於sbglasius並未指向動態發現者。 –

+0

對,都是正確的 –

回答

7

使用methodMissing並不昂貴,因爲Grails在MOP中僅在第一次執行未找到的方法時才創建新方法。子順序執行發生在新創建的方法上。

考慮一個具有許多屬性的域類。如果所有findBy *,findAlLBy *,countBy *等排列都應該在編譯時創建,那麼這些類很容易變得非常大。通過使用methodeMissing,只會創建運行時實際使用的方法。

5

據我瞭解代碼,這些信息已過時。這些方法被注入metaClasses。看看grails-hiberante插件的代碼。

HibernateGrailsPlugin.groovygithub)線49執行每個時間上下文開始:

def doWithDynamicMethods = HibernatePluginSupport.doWithDynamicMethods 

然後,打開一個HibernatePluginSupportgithub),然後按照流程:

/*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行中的每個實體。方法由方法registerNamespaceMethods的587行生成。據我瞭解,這些方法直接從行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源代碼時的發現。