JBossベースのWebアプリケーションでJAXBContext.newInstance操作を使用します。私が理解しているように、この操作は非常に重いものです。マーシャラークラスの2つの一意のインスタンスのみが必要です。
私の最初の提案は、クラスのロード時にこれら2つのインスタンスを1回だけ初期化する静的初期化ブロックを用意することです。
public class MyWebApp {
private static Marshaller requestMarshaller;
private static Marshaller responseMarshaller;
static {
try {
// one time instance creation
requestMarshaller = JAXBContext.newInstance(Request.class).createMarshaller();
responseMarshaller = JAXBContext.newInstance(Response.class).createMarshaller();
} catch (JAXBException e) {
e.printStackTrace();
}
}
private void doSomething() {
requestMarshaller.marshall(...);
responseMarshaller.marshall(...);
...
}
}
これが合理的な解決策である場合、私は自分の質問に答えたと思いますが、これがこれを行う正しい方法であるかどうかを知りたいですか?
JAXB実装( Metro 、 EclipseLink MOXy 、 Apache JaxMe など)は通常、JAXBContext.newInstance
呼び出し中にメタデータを初期化します。すべてのOXMツールは、ある時点でマッピングメタデータを初期化し、この操作のコストを最小限に抑えるようにする必要があります。ゼロコストでそれを行うことは不可能なので、一度だけ行うのが最善です。 JAXBContextのインスタンスはスレッドセーフであるため、作成する必要があるのは1回だけです。
JAXB 2.2仕様、セクション4.2 JAXBコンテキストから:
JAXBContextインスタンスの作成に伴うオーバーヘッドを回避するために、JAXBアプリケーションはJAXBContextインスタンスを再利用することをお勧めします。抽象クラスJAXBContextの実装はスレッドセーフである必要があるため、アプリケーション内の複数のスレッドが同じJAXBContextインスタンスを共有できます。
MarshallerとUnmarshallerのインスタンスはスレッドセーフではなく、スレッド間で共有してはなりません。作成が軽量です。
JAXBContextは常に静的である必要があり、スレッドセーフです。
マーシャラーとアンマーシャラーは安価であり、スレッドセーフではありません。 JAXBContextを一度作成し、すべての操作に対してマーシャラー/アンマーシャラーを作成する必要があります
public class MyWebApp {
private static JAXBContext jaxbContext;
static {
try {
// one time instance creation
jaxbContext = JAXBContext.newInstance(Request.class, Response.class);
} catch (JAXBException e) {
throw new IllegalStateException(e);
}
}
private void doSomething() {
jaxbContext.createMarshaller().marshall(...);
...
}
}
同じマーシャラーを使用してすべてをマーシャリングします(コンテキストを作成するときにすべてのクラスを追加します)。
最近、JAXBContext.newInstanceを使用してパフォーマンステストを行いました。結果は、ここに記載されています。
http://app-inf.blogspot.com/2012/10/performance-tuning-logging-right-way.html
〜195のクラスが生成されたかなり大きなスキーマを使用して、1つのスレッドによって呼び出された場合、完了するまでに〜400msかかりました。 20個のスレッドによって同時に呼び出されると、CPUの競合が発生し、完了するまでに最大5000ミリ秒かかりました。マーシャラーの作成と小さなオブジェクトのオブジェクトのシリアル化は、わずか14ミリ秒です。
Javax.xml.bind.JAXBを使用できます。直接マーシャルとアンマーシャルの方法があります。したがって、JAXBのインスタンス作成について心配する必要はありません。
例えばJAXB.unmarshal(inputStream/inputFile、outputClassExpected)またはJAXB.marshal(jaxbObject、xmlOutputFile/xmlOutputStream)