1

質問

私はJavaとSpringに不慣れで、XMLとは異なるオブジェクトをマーシャリングして処理するコードを構造化する方法を知りたいです。Springを使用する前のコードJAVAコードを変換しています。私はこれにアプローチした方法をおそらく間違っていますが、誰かが物事を再構築する方法についていくつかの指針を提供できれば、それは大いに役立つでしょう。Springのドキュメントをたくさん読みましたが、そこにあるものをコードに適用するのは難しいと感じています。

状況

単純な例は多くのコードであるため、コードツリー全体を投稿するつもりはありません(これが問題です)。そのため、方法について説明します。

CLASSAとCLASSBの2つのクラスのXMLとスキーマがあります。xjcを使用してJAVAラッパーを生成しました。JAXBマーシャラーのラッパーであるJAVAクラスがあります。ラッパーには、構築時にマーシャリングするクラスのクラス名とパッケージ名を付ける必要があります。

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のインスタンスごとに1つの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ファイルは、固定名とローリングカウンターを持つファイルで一度に1つずつ配信されます(そしてそれを変更することはできません)。そのため、ファイル名からファイル内のオブジェクトを特定できません。処理しようとしているファイルにどのオブジェクトタイプが含まれているかをチェックする小さなユーティリティ関数があります。

次に、次の機能があります。

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;
}

そのため、オブジェクト名を取得して、コンテキストから適切なBeanを取得しています。これは、Springのオブジェクトプールなどを使用して、さまざまなオブジェクトのJaxbWrappersを多数保持できることを意味します。しかし、私がこれを実装した方法は私には間違っていると感じています。myContext.getBean( "jaxbParser_"+JaxbWrapperBeanを取得するxmlObjectTypeメソッドが好きではありません。

だから私の質問は:このコードを構造化するより良い方法はありますか?いくつかの簡単なポインタをいただければ幸いです。

追加の複雑さ

これは、現時点で物事が本当に手に負えなくなるところです。マーシャリング段階が完了すると、クラスタイプごとにいくつかの異なるポストプロセッサがある後処理段階があります。これらのそれぞれにSpringBeanがあり、以下を使用してアプリケーションコンテキストから取得しています。

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

どこ:

  • xmlObjectTypeは、ファイルからオブジェクトタイプを読み取ることによって設定される文字列CLASSAまたはCLASSBです(上記のように)。
  • ProcessorTypeは、コマンド行から設定される文字列です。

proceesorTypeを設定するには、アプリケーションの起動時に次のようにします。

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

繰り返しますが、これは物事を行うための正しい方法ではないと思いますが、現時点で私が得た最高の方法です:-(。

より一般的な質問は、JAXBとSpringがどのように連携するかということだと思います。現実の世界では、非常に大きくて複雑なCLASSAとCLASSBがたくさんあります。xjcによって生成されたこれらのJavaクラスがあります。xjcを使用しているので、jaxbを使用する必要があります(私は推測します)。問題は、春の世界でそれをどのように行うかです。

または、JAXBを削除してSpringコンポーネントを使用できますか?xjc以外のすべてのクラスを生成するには、他の何かを使用する必要があります。しかし、私はそのタスクを実行するものを見つけることができません

4

1 に答える 1

1

ここではたくさんのことが起こっているので、春の外でこれを行うことができるはずの@BlaiseDoughanに同意する必要があります。

Springはオブジェクトプーリング(aop)を実行し、オブジェクトを破棄するための管理機能を備えていますが、そのような目的で使用しないでください。基本的getBeanに、実行時に何をしているのかを理解していない限り、いつでも間違って実行していることになります。

Springは、動作ベースのシングルトンを管理するためのものです。

だからあなたがしたいのは、どのように振る舞いをするシングルトンを作ることができるかを考えることです...あなたの場合、あなたはのファクトリーを作りたいですJaxbWrapper.class(そして私はSpringの特別な豆ファクトリーを意味しません)。

だから次のようなもの:

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を作成するためのさまざまな戦略を作成する場合は、実装で一種の戦略インターフェイスとワイヤを作成できます。しかし、私はあなたがそのような複雑さを必要としないと思います。

基本的に、これらのヒントを要約します。

  • シングルトンとほとんどのSpringマネージドBeanはスレッドセーフでなければならないことに注意してください。
  • public staticこれは邪悪なシングルトンにつながるので、ユーティリティのためにメソッドを予約してください。
  • 多くの場合、オブジェクトの作成には、独自のファクトリパターンを作成するのが最善です。
  • JAXBのファクトリサポートを確認することをお勧めします。
于 2012-09-29T14:36:10.467 に答える