2012-09-28 41 views
1

的等待處理的問題如何構建春季代碼JAXB marhalling和XML

我是新來的Java和春天,我想知道如何組織代碼編組從XML,然後不同的對象處理它們。我正在轉換一些代碼JAVA代碼,在我使用spring之前。我知道我已經接近這個的方式,可能是錯誤的,但如果有人可以提供一些關於如何重構「春天的方式」,這將有助於很多的指針。我已經閱讀了很多Spring文檔,但是我發現很難將其中的內容應用到我的代碼中。

現狀

我不會因爲即使張貼整個代碼樹和簡單的例子是很多的代碼(這是問題)。所以我只會描述這個方法。

我有兩個類的XML和模式CLASSA & CLASSB。我使用xjc生成了JAVA包裝器。我有一個JAVA類,它是JAXB編組的封裝器。包裝需要被賦予類的名稱和要編譯的類的包名稱。

public JaxbWrapper(String ClassName, String packageName) throws ClassNotFoundException, InstantiationException, 
     IllegalAccessException, JAXBException 
{ 

    this.packageName = packageName; 

      // set the context is the expensive operation 
    setJAXBContext(Class.forName(fullJaxbClassName(ClassName)).newInstance()); 

      // get the schma from preset schema dir 
    schemaFileName = findSchema(ClassName); 
    myMarsheller = jc.createMarshaller(); 
    myMarsheller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); 
} 

我已經爲ClassA和ClassB的JaxBWrapper的每個實例獲得了一個bean。它們幾乎是相同的,所以只顯示A級的一個。

<bean id="jaxbParser_CLASSA" class="org.test.JAXB.JaxbWrapper" 
    lazy-init="true" scope="prototype"> 
    <constructor-arg index="0" type="java.lang.String" 
     value="CLASSA" /> 
    <constructor-arg index="1" type="java.lang.String" 
     ref="testPackage" /> 
    <property name="encoding" ref="xmlEncoding" /> 
</bean> 

幫倒忙來處理XML文件,我有與固定名稱和滾動計數器(我不能更改)交付一次一個文件。所以我無法從文件名中知道文件中有什麼對象。我有一個小實用程序函數,用於檢查我正在嘗試處理的文件中的哪個對象類型。

然後我有以下功能:

public static Object loadXML(String xmlFile, String fileName) throws Exception 
{ 
    InputStream iStream = XmlUtils.openFile(xmlFile); 
    String xmlObjectType = XmlUtils.getObjectTypeFromXML(xmlFile); 
      // get the right JAXB processor 
    JaxbWrapper jaxB = myContext.getBean("jaxbParser_" + xmlObjectType , JaxbWrapper.class); 
    Object obj = jaxB.objectFromXML(iStream, xmlObjectType , fileName); 
    return obj; 
} 

所以我採取了對象名稱,並得到從上下文正確的豆。這意味着我可以使用諸如Spring的對象池之類的東西來爲不同的對象容納大量的JaxbWrappers。但是我實施這種方式對我來說感覺不對。我不喜歡使用JaxbWrapper bean的myContext.getBean(「jaxbParser_」+ xmlObjectType方法

所以我的問題是:是否有更好的方法來構造這段代碼?幾個簡單的指針會非常多讚賞。

額外的複雜性

這是哪裏的東西,此刻,變得非常難以管理。一旦封送處理階段已經完成了我有哪裏有幾種不同的後處理器後處理階段每個類的類型。我有春豆對於這些,我用讓他們從應用程序上下文:

myContext.getBean(xmlObjectType + "_" + processorType + "_" + xmlObjectType); 

其中:

  • xmlObjectType是一個字符串CLASSA或CLASSB通過讀取設定對象類型(如上所述)。
  • processorType是從命令行設置的s字符串。

要設置proceesorType我在做應用程序啓動時如下所示。

if (line.hasOption("file")) 
    { 
     processorType = "FileProcessor"; 
    } 
    if (line.hasOption("print")) 
    { 
     processorType = "PrintProcessor"; 
    } 

同樣,我不認爲這是做事的正確方法,但是這是我的時刻了:-(最好的。

我猜的更普遍的問題是, JAXB和Spring是如何協同工作的?在現實世界中,我有很多非常龐大而複雜的CLASSA和CLASSB,我已經爲這些由xjc生成的java類提供了服務,因爲我使用的是xjc,所以我必須使用jaxb(我猜) 。問題是如何在春天世界做到這一點

或者我可以擺脫JAXB和使用春季補償onent。我需要使用別的東西來生成除xjc以外的所有類。但我找不到任何可以執行該任務的任何東西

+0

我會建議你把事情分解成小塊。嘗試Spring環境之外的JAXB映射,以確保它們可以獨立運行。一旦你在春季有這樣的因素。一旦你有這個擔心集中資源等 –

+0

謝謝,我可能不夠清楚。我有一些代碼可以完成我描述的大量類類型(大約40)的任務。它確實有效,所以我不問我能做到這一點,因爲我知道它會起作用。問題在於它將成爲維修的噩夢,我無法逃避的感覺是必須有更好的方式,但我無法弄清楚它是什麼。我從一個大的case語句開始,它在對象類型上選擇了正確的JAXB編組器和處理器。我剛剛用Spring的getBean()調用替換了這個bean,其中Bean名稱是串聯的字符串。 – DUFF

回答

1

這裏有很多事情要做,我必須同意@BlaiseDoughan,你應該可以在Spring之外做到這一點。

雖然Spring確實做了對象池(aop)並且有一些管理器用於丟棄對象,所以不應該使用它。基本上任何時候你在運行時都要做getBean,除非你知道你在做什麼,你做錯了。

Spring是用於管理基於行爲的單例。

所以你想要做的是想怎麼做一個單身人士做這個行爲...在你的情況下,你想要一個工廠JaxbWrapper.class(我不是指Spring的特殊bean Factory)。

因此,像:

public class JaxbWrapperFactory { 
    Map<String, JaxbWrapper> pool = new ConcurrentHashMap(); // recommend Guava's Cache 

    public JaxbWrapper create(String ClassName, String packageName) throws ClassNotFoundException, InstantiationException { } 

    public Object loadXML(String xmlFile, String fileName) throws Exception { 
    /// use create from above 
    } 

} 

現在在春天,你只能絲JaxbWrapperFactory

如果您想根據輸入xml創建不同的策略來創建JaxbWrapper,您可以在實現中製作策略接口和連線。但我認爲你不需要那麼複雜。

基本上熬下來,這些提示:

  • BE-知道,單身人士和大多數春季管理的bean必須是線程安全的。
  • 儲備public static只有實用的方法,因爲這導致邪惡的單身人士。
  • 通常情況下,創建對象最適合製作自己的工廠模式。
  • 你可能想看看JAXB's factory support
+0

謝謝,我想我現在明白了。我試圖以錯誤的方式使用Spring。我應該將JaxbWrapper處理器的管理委派給某種工廠,並且執行後處理。連接這兩者的策略可以由這兩者中的一個或附加組件來表示。然後我可以使用Spring將它們連接起來。但試圖表達連接getBeans和應用程序上下文的邏輯是錯誤的方法。 – DUFF

+0

我可以問:當你說**「基本上任何時候你在運行期間都在做getBean,除非你知道你在做什麼,你做錯了」**。該maean是否使用了getBean(),如[給出這個問題]中給出的答案(http://stackoverflow.com/questions/4794060/strategy-pattern-and-dependency-injection-in-spring)應該是認爲錯了? – DUFF

+0

閱讀詹姆斯評論:http://stackoverflow.com/questions/4794060/strategy-pattern-and-dependency-injection-in-spring#comment5313087_4794070。我在說你應該連接戰略地圖。 Spring支持java.util.Map的接線。 –