J2SEおよびJ2EEアプリケーションの構成:標準的な方法とその代替

現在、Javaアプリケーションを構築するための多くのオプションがあり、それらの構成のタスクはさまざまな方法で解決されています。
この記事では、標準のJDKツールを使用してJ2SEおよびJ2EEアプリケーションを構成する手法と機能、およびこれらの方法の代替方法について説明します。


J2se


java.util.Properties

アプリケーションを構成する古典的な方法は、 java.util.Propertiesクラスを使用することです。 内部はすべて非常に単純です。実際、デフォルト値を保存および初期化する機能を備えたjava.util.Mapインターフェースの拡張機能です。

いくつかの欠点があります。


このマイナスのリストは、実際の生産で純粋なプロパティを使用することは非効率的であることを示唆しています。 このアプローチで最初に遭遇するのは、構成を変更した場合はアプリケーションの再起動が必要であるというサービス部門からの苦情です。
私の意見では、これの負の結果の可能性が最も高い:


「設定ファイルとイベント生成サブシステムの再読み込みを追加するだけでいい」ということに反対することができます。はい、本当です。これはすべて、すでに明らかではないように見えますが、常に表示されます。
次の記事では、Commons Configurationと、そこで概説した問題がどのように解決されるかについて説明します。
それまでの間、J2EEアプリケーションの一般的な構成オプションを検討してください。

J2EE-EJB3


リソース注入

EJBアプリケーションを構成する最も簡単な方法の1つは、デプロイメント記述子(ejb-jar.xml)を使用することです。

< enterprise-beans >
< session >
< ejb-name > MyService </ ejb-name >
< env-entry >
< env-entry-name > myProperty </ env-entry-name >
< env-entry-type > java.lang.String </ env-entry-type >
< env-entry-value > 100500 </ env-entry-value >
</ env-entry >
</ session >
</ enterprise-beans >



記述子では、名前(env-entry-name)、タイプ(env-entry-type)、およびパラメーター値(env-entry-value)を指定します。その後、 Resourceアノテーションを使用して注入します
@Resource(name = "myProperty" )
private String myProperty;
@PostConstruct
public void postConstruct() {
System. out .println( "myProperty = " + myProperty);
}



このアプローチにより、次のタイプのパラメーターを操作できます。


欠点には、パラメーターを変更すると再適用が行われ、その結果、一定期間の動作不能が発生するという事実が含まれます。
再展開ポリシーは、アプリケーションサーバー上のアプリケーション記述子変更スキャナーの設定に依存します。
そのため、たとえば、JBoss 5.x-6.xアプリケーションサーバーの場合、ejb-jar.xmlを変更すると、再障害が発生することが保証されます(もちろん、スキャナーがオフになり、再デプロイがJMXコンソールを介して手動で行われない限り)。

外部設定ファイルを使用する


非常に有用なドキュメントがあります-EJBテクノロジーの制限です 。 このドキュメントには、ファイルリソースを使用しないという明確な指示があります。 表示は次のとおりです。


ただし、ファイルがEEアプリケーション内にある場合、ファイルを読み取り専用データソースとして使用することは許容されます。 実際、クラスター展開の場合、EEアプリケーションはすべてのノードで同じになります。

したがって、EEアプリケーション内のjava.util.Propertiesの古典的なユースケースに到達します。
@Stateless(mappedName = "BackendService" )
public class BackendServiceBean implements BackendServiceLocal {

private static final String P_PROPERTIES = "myProperties.properties" ;

private static final Logger logger = LoggerFactory.getLogger(BackendServiceBean. class );

@EJB
private DataRepositoryLocal dataRepository;

@Resource(name = "remoteURL" )
private String remoteURL;

private Properties properties;

@PostConstruct
private void init(){
InputStream propertiesResource = null ;
try {
propertiesResource = getClass().getResourceAsStream(P_PROPERTIES);
properties = new Properties();
properties.load(propertiesResource);
} catch (Exception e) {
logger.error( "Error" , e);
} finally {
if (propertiesResource != null ){
try {
propertiesResource.close();
} catch (Exception e) {
logger.error( "Error" , e);
}
}
}
}

public Properties getProperties() {
return properties;
}



欠点は、以前にJ2SEおよびjava.util.Propertiesで示したものと同じです。 さらに、J2EEのコンテキスト内にあり、ファイルの変更を監視してイベントを生成するストリームを追加することはできません(J2EEアプリケーションではストリームを作成できないため)。
「アプリケーションがプロパティプロキシオブジェクトでgetPropertyを呼び出すたびに、.propertiesファイルを再読み込みする必要があります。」 はい、できますが、この場合、アプリケーションの高性能を忘れてください-ファイルを読み取り用に開いて、バッファーにロードし、解析してプロパティのインスタンスを作成すると、処理に顕著な遅延が生じます。
このソリューションを使用する正しい方法は、静的な読み取り専用設定のみを保存することです。

その他のオプション


前述のオプションには欠点があります-正しい作業は静的パラメーターでのみ提供されます。 パラメータの現在の値を常に取得する必要がある場合は、他のオプションを探す必要があります。

J2EEアプリケーションの場合、これらのオプションは次のとおりです。


J2EEおよびJ2SEアプリケーションの両方で、さまざまなフレームワークを使用したり、構成の問題を解決するために調整した独自のフレームワークを作成したりできます。

J2EE-サーブレット


サーブレットを構成するとき、web.xml記述子を処理します。この記述子では、必要なパラメーターを設定します。
< web-app version ="2.5" xmlns ="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation ="http://java.sun.com/xml/ns/j2ee java.sun.com/xml/ns/j2ee/web-app_2_5.xsd" >

<!-- -->
< context-param >
< param-name > myContextParam1 </ param-name >
< param-value > value1 </ param-value >
</ context-param >
< context-param >
< param-name > myContextParam2 </ param-name >
< param-value > value2 </ param-value >
</ context-param >

<!-- -->
< filter >
< filter-name > myFilter </ filter-name >
< filter-class > net.universe.filter.EntityAccessFilter </ filter-class >
< init-param >
< param-name > checkType </ param-name >
< param-value > ldap </ param-value >
</ init-param >
< init-param >
< param-name > myParam </ param-name >
< param-value > true </ param-value >
</ init-param >
</ filter >

<!-- -->
< servlet >
< servlet-name > MyServlet </ servlet-name >
< servlet-class > net.universe.servlet.MyServlet </ servlet-class >
< init-param >
< param-name > servletParam1 </ param-name >
< param-value > paramValue1 </ param-value >
</ init-param >
< load-on-startup > 1 </ load-on-startup >
</ servlet >
</ web-app >



セットアップでは、param-value構成アイテムを変更します。 ファイルを変更して保存した後、再適用も行われ、その後一定期間操作できなくなります。 この設定方法は、ejb-jar.xmlを使用したバリアントと同様に、アプリケーション中に変更されることのないパラメーターに最適です。 ここでランタイム設定を操作するためのテクニックは、EJBの場合に使用されるものと似ています-データベース、JNDIなど...

すべてに共通


System.getProperty

これらすべての構成方法に共通するのは、Javaアプリケーションの起動行に渡されるシステムパラメーターの使用です。
java -DmyProperty1=myPropertyValue1 -DmyProperty2=myPropertyValue2 -jar myapp.jar


その後、java.lang.Systemクラスを使用して構成パラメーターを取得できます。
String string = System.getProperty("myProperty1");


この方法は、J2EEでの作業のコンテキストで限定的に適用可能です-クラスターモードで作業する場合、システム変数がすべてのノードに到達しない場合があります。 「できる」理由-たとえば、JBossアプリケーションサーバーにはSystemPropertiesServiceサービスがあり、その構成のフラグメントをEEアプリケーションに含めることができるためです(つまり、「システム」変数はすべてのノードにあります。アプリケーションの一部として構成ファイルで)。

多くの場合、この構成方法は、必要に応じてコードにいくつかの新しい条件チェックをすばやく追加するために使用されます。
たとえば、非常に高速であるため、条件を追加し、クラスをコンパイルして、既にデプロイされたEEアプリケーション/ライブラリで置き換え、その後に再デプロイ/再起動する時間しかありません。
もちろん、このオプションをグッドプラクティスと呼ぶことはできませんが、それでも実生活では起こります。

また、このアプローチの代わりに、アスペクト指向プログラミング/バイトコードへの注入を使用することもできます。 これらの手法により、元のアプリケーションを変更せずに残すことができますが、特に実稼働システムでのAOPインターセプター(インターセプター)の動的な実装に関しては、より高いレベルの開発者スキルが必要です。

JMX


JMXは、アプリケーションの構成など、多くのことに便利なツールです。 java.util.Properties/Commons Configurationの使用と公開されたMBeanを、パラメーターの値を設定/取得する方法と組み合わせて使用​​できます(インストール中に、properties.setPropertyへの委任が続きます)。
構成ファイルにはアクセスできないが、ネットワークを介してMBeanServerにはアクセスできる場合、同様のソリューションを正常に適用できます。

このアプローチの欠点は次のとおりです。


今のところすべてです。

近い将来、Commons Configurationライブラリに関する記事が完成し、J2SEおよびJ2EEアプリケーションで構成ファイルを操作する可能性が大きく広がります。

ご清聴ありがとうございました!

Source: https://habr.com/ru/post/J129383/


All Articles