2016-04-30 66 views
2

我有一個這樣的文件:通屬性/變量,進口豆

beans { 
    "$id"(String, "${val}") 
} 

我希望能夠通過IDVAL

如果我在同一個文件中定義它們,它就可以工作。如果我在加載應用程序上下文時使用綁定來定義它們,它也可以工作。但我希望能夠做到這樣的事情:

beans { 

    def id = "foo" 
    def val = "bar" 

    importBeans("path_to_the_above_file") 

} 

想法是通過每次覆蓋bean id和值多次導入這些bean。基本上,將其用作模板。不知道它可以完成。但我真的很討厭在導入的文件中複製所有的bean只是爲了改變ID。

這是我想有一個最終的結果是什麼:

beans { 

    def id = "foo" 
    def val = "bar" 

    importBeans("path_to_the_above_file") 

    id = "foo2" 
    val = "bar2" 

    importBeans("path_to_the_above_file") 

    foo3(String, foo) 
    foo4(String, foo2) 
} 

好吧,我把它通過使用元類作爲答案提示工作:

beans { 

    GroovyBeanDefinitionReader.metaClass.id = "foo" 
    GroovyBeanDefinitionReader.metaClass.val = "bar" 

    importBeans("classpath:config/mytest.groovy") 

    setId("foo2") 
    setVal("bar2") 

    importBeans("classpath:config/mytest.groovy") 

} 

唯一的缺點是我需要將ExpandoMetaClass初始化,並且我無法從Spring Groovy定義中找到一種方法。我需要調用醚ExpandoMetaClass.enableGlobally(),或在項目中的常規類,並做類似GroovyBeanDefinitionReader.metaClass.init = {}

+0

我的意思通過使用元級,是添加一個方法。例如:'importBeans(String path,Map variables)'。注意:混淆元類應該在..本身之外完成。在您的應用初始化之前。注意:創建一個實例時,它將獲得它自己的類的元類的私有副本。因此,如果您然後更改類的元類,實例將不會看到更改。 –

回答

1

GroovyBeanDefinitionReader不提供要進口大豆,而方法允許你傳遞一個綁定。它創建了它自己的結合各此,見https://github.com/spring-projects/spring-framework/blob/master/spring-beans-groovy/src/main/java/org/springframework/beans/factory/groovy/GroovyBeanDefinitionReader.java#L232

你可以做的卻是這樣的:

beans { 
    [ 
     [id: 'foo', val: 'bar'], 
     [id: 'foo2', val: 'bar2'] 
    ].each { 
     invokeMethod(it.id, [String, it.val]) 
    } 
} 
+0

不幸的是,我不明白invokeMethod會如何幫助。它解決了String bean的小問題。但是我包含的文件實際上非常複雜,並且包含大量的bean。你不能通過任何類型的參數很不方便。我目前通過bean作爲配置的手段,但當我需要創建多個副本時它不起作用。看來,處理它的唯一方法是複製完整的包含文件並手動更改所有的bean ID。看起來像配置惡夢,但沒有其他明顯的選擇。 –

+0

沒有必要失去希望!如果你研究我鏈接到的源代碼,我敢打賭,你可以弄清楚它足夠寫出一個你需要的方法。然後你可以通過元類添加這樣的方法。 –

+0

謝謝。從不做任何元類,但我會嘗試。如果我找到解決方案,我會在這裏發佈代碼。我正在考慮創建一個可以加載帶綁定文件的bean,然後公開它的bean。但是如果元類能夠更好地發揮作用,我會隨之而去。 –

0

其實我已經想通了。正如我上面所說的,當加載上下文時,導入的bean實際上會看到以編程方式設置的綁定。我只需要弄清楚如何從groovy config腳本中獲得該綁定。有2(或更多的方式)。一是創建任何豆或任何類別,並在其關閉設置變量:

init(Object) { 
    getBinding().setVariable("id", "food") 
    getBinding().setVariable("val", "bar") 
} 

另外,我認爲更好的辦法:

def beanBinding = getBinding().getProperty("beans").getBinding() 
beanBinding.setVariable("id", "food") 
beanBinding.setVariable("val", "bar")