序文
現在、Tomcat、Struts2、NettyなどのほとんどのJavaアプリケーションは、私たちがよく知っている、それらを数えることができない、
普遍性を満たすために、ユーザーが関数をカスタマイズするために構成ファイルが提供されます。
Nettyなどのネットワークフレームワークもあり、ほぼ完全に構成された駆動型であり、通常、そのようなソフトウェアを「マイクロカーアーキテクチャ」と呼びます。
あなたがそれを構成するものは何でも、それはそれが何であるかです。
それはあなたがそれを設定するものです。
最も一般的な構成ファイル形式は、XML、プロパティ、その他のファイルです。
この記事では、構成の読み込みにおける最も一般的で一般的なシナリオについて説明します。これは、構成ファイルをJavaのPojoオブジェクトにマッピングすることです。
さまざまなロード方法を実装する方法について説明します。たとえば、一部の構成はローカルXMLファイルからロードされますが、一部の構成はローカルプロパティファイルからロードする必要があります。さらに、一部の構成はネットワークを介してロードする必要があります。
このような構成ロードメカニズムを実装する方法により、このメカニズムが得られた後、コードの読み込み構成がどこにでも広がらず、スケーラブルで管理しやすくなります。
ローダーを構成します
まず、構成ローダーが必要です。この構成ローダーは、さまざまなロード方法を搭載できます。したがって、インターフェイスを使用して次のように説明します。
/** * * * @author bean * @date 2016年1月21日11:47:12 am * @version 1.0 * */public interface iconfigloader <t> {/** * @return * @throws Configexception */public Toad()throws configexception;}しかし、なぜこのインターフェイスでジェネリックを宣言する必要があるのでしょうか?
明らかに、構成ローダーを使用する場合は、この構成ローダーに、ロード後に取得する必要がある結果を指示する必要があります。
たとえば、構成をロードしてAppleConfigオブジェクトを取得する場合は、上記のインターフェイスを使用できます。
ICONFIGLOADER <AppleConfig> loader = new AppleConfigLoader <AppleConfig>(); AppleConfig config = loader.load();
そのため、構成ファイルの情報をAppleConfigオブジェクトに変換し、このAppleConfigオブジェクトインスタンスを取得できます。
これまでのところ、AppleConfigLoaderが構成ファイルをロードする方法の特定の労力を実装している限り、構成を簡単にロードできるようです。
それは言うことができますが、プロパティ、DOM、SAX、または一部のサードパーティのオープンソースライブラリを介したロードなど、構成がさまざまな方法でロードされる可能性があるということではありません。
したがって、ローダーの構成に加えて、もう1つの役割、読み込み方法を構成するプロバイダーも必要です。 iconfigproviderと呼びましょう。
ロードメソッドのプロバイダーを構成します
構成読み込み方法のプロバイダーは、構成ローダーにロード方法を提供できます。つまり、構成ローダーにオブジェクトを提供します。
DOMを介してロードされた場合、プロバイダーはローダーにドキュメントオブジェクトを提供します。
プロパティを介してロードされた場合、プロバイダーはローダーにプロパティオブジェクトを提供します。 Apache-Commons-Digester3(Tomcat Configuration Loading)などのサードパーティクラスライブラリが提供する方法を介してロードされた場合、プロバイダーはローダープロバイダーに消化剤オブジェクトを提供します。それはすべて、ローダーの構成に必要なオブジェクトのみを提供するだけですが、それ自体は負荷の構成の労働に関与しません。
インターフェイスiconfigproviderを使用して、このプロバイダーを定義します
/** * * * @author bean * @date 2016年1月21日11:54:28 am * @version 1.0 * */public interface iconfigprovider <t> {/** * @return * @return * @throws Configexception */public t sultion()slows Configexception;}ジェネリックを宣言するためにここに<t>があるのはなぜですか?
プロバイダーが必要な場合は、少なくともプロバイダーに提供するものを伝える必要があります。
したがって、プロバイダーが提供するものはこれによって決定されます。
同時に、最初に工場を建設し、特定のプロバイダーを生産させることができます。
/** * * * @author bean * @date 2016年1月21日11:56:28 am * @version 1.0 * */public class configproviderFactory {private configproviderFactory(){show new unsupportedoperationexception( "工場クラス:" + getClass()。 } public static Iconfigprovider <document> recratedocumentProvider(string filepath){return new DocumentProvider(filepath); } public static Iconfigprovider <properties> createPropertiesProvider(String filepath){return new PropertiesProvider(filePath); } public static Iconfigprovider <Digester> createdgesterProvider(string filepath){return new DigesterProvider(filepath); }}特定の構成ローダーの実装を開始できますか?
まだ大丈夫ではありません!
この時点で、Apple.xmlという構成ファイルがあるとします。また、このApple.xmlをDOMを介してAppleConfigオブジェクトにロードする必要があります。
そのため、まず第一に、プロバイダー工場を通じてドキュメントを提供できるプロバイダーを作成したいと思います。次に、このプロバイダーを取得し、ドキュメントオブジェクトを取得するためのその提供方法を呼び出すことができます。
ドキュメントオブジェクトを使用すると、構成の読み込みを開始できます。
ただし、Bananaconfig、Pearconfigをロードしたい場合は......ステップは同じです。したがって、いくつかのデフォルトの共通動作を実装するには、抽象クラスも必要です。
/** * * * @author bean * @date 2016年1月21日午前11時599:19 AM * @version 1.0 * * */public abstract class abstractconfigloader <t、u> Iconfigloader <t> {protected iconfigprovider <u> vovider; Protected AbstractConfigLoader(iconfigprovider <u> provider){this.provider = provider; } / * * @see iconfigloader#load() * / @override public t load()throws configexception {return load(getProvider()。 } public abstract t load(u loaderSource)configexceptionをスローします。 protected iconfigprovider <u> getProvider(){return this.provider; }}各構成ローダーには、プロバイダーを受信するパラメーターコンストラクターがあります。
ジェネリックは、AppleConfigまたはBananconfigをロードするかどうかを示します。汎用<u>は、ロードするロード方法を示しています。ドキュメント、プロパティ、または他のものです。
実用的なアプリケーションの例
野菜市場構成ファイルMarket.xmlがあります。これは、2つの製品、つまりリンゴと卵など、野菜市場の製品を構成しています。
<market> <pople> <color>赤</color> <価格> 100 </rish> </apple> <egg> <weight> 200 </weight> </egg> </market>
各ストールのボスの名前の構成ファイル、所有者。propertiesもあります
port1 = Steve Jobsport2 = Bill Gatesport3 = Kobe Bryant
最初に次のクラスを定義しましょう。
MarketConfig.java
/** * * * @author bean * @date 2016年1月21日午後11時37分 *プライベートEggconfig Eggconfig; Private OwnerConfig OwnerConfig; public Appleconfig getAppleConfig(){return appleconfig; } public void setappleconfig(appleconfig appleconfig){this.appleconfig = appleconfig; } public Eggconfig geteggConfig(){return gigconfig; } public void seteggconfig(eggconfig eggconfig){this.eggconfig = eggconfig; } public OwnerConfig getOwnerConfig(){return OwnerConfig; } public void setOwnerConfig(ownerconfig ownerconfig){this.OwnerConfig = ownerConfig; }}Appleconfig.java
/** * * * @author bean * @date 2016年1月21日午後11:03:45 pm * @version 1.0 * */public class appleconfig {private int price;プライベートストリングカラー; public void setPrice(int price){this.price = price; } public int getPrice(){return this.price; } public void setcolor(string color){this.color = color; } public string getColor(){return this.color; }}eggconfig.java
/** * * * @author bean * @date 2016年1月21日午後11:03:58 pm * @version 1.0 * */public class Eggconfig {private int weight; public void setweight(int weight){this.weight = weight; } public int getWeight(){return this.weight; }} ownerconfig.java
/** * * * @author bean * @date 2016年1月21日午後11:04:06 pm * @version 1.0 * */public class ownerconfig {private map <string、string> owner = new hashmap <string、string>(); public void addowner(string portname、string owner){this.Owner.put(portname、所有者); } public string get OwnerbyportName(string portname){return this.Owner.get(portname); } public map <string、string> getowners(){return collections.unmodifiablemap(this.Owner); }}この例には、DOMとプロパティロード方法の2つの構成負荷方法があります。
そのため、当社のプロバイダーは、2つのプロバイダーで工場を建設する必要があります。
そして、2つの構成ローダーを定義する必要があります。
ownerconfigloader
/** * * * @author bean * @date 2016年1月21日午後11時24:50 * * @version 1.0 * */public class ownerconfigloader extends abstractconfigloader <ownererconfig、properties> {/** * @param provider */protected ownerconfiger(suprovider <properties> probider> probider> probider } / * * @see abstractconfigloader#load(java.lang.object) * / @override public Ownerconfig load(Properties Props)throws configexception {ownerconfig ownerconfig = new ownerconfig(); / ** * Propsを使用してOwnerConfigのプロパティ値を設定 * *ここのコードは省略されています */ return ownerconfig; }}次に、MarketConfigLoaderがあります
intalg.w3c.dom.document;/** * * @author bean * @date 2016年1月21日午後11:18:56 pm * @version 1.0 * */public class marketconfigloader <marketconfig、document> {/** * @paramfiglider extected marketconfiglowder super(プロバイダー); } / * * AbstractConfigLoader#LOAD(java.lang.object) * / @Override public MarketConfig load(document document)throws configexception {marketconfig marketconfig = new MarketConfig(); AppleConfig AppleConfig = new AppleConfig(); eggconfig eggconfig = new Eggconfig(); / ** *ここでドキュメントを処理すると、 * appleconfigとeggconfg *を取得できます。 MarketConfig.seteggConfig(Eggconfig); / ** * OwnerConfigはロードするためにプロパティを必要とするため、XML *ではないため、ここでは新しいOwnerConfigLoaderを作成し、OwnerConfigをロードするために委任する必要があります */ OwnerConfigLoader ownerconfigloder = new ownerconfigloader(configProviderFactory.CreatePropertiesProvider(Your_File_Patide); ownerconfig ownerconfig = ownerconfigloader.load(); MarketConfig.SetownerConfig(OwnerConfig); Return MarketConfig; }}では、どのようにしてアプリケーションレベルでMarketConfigを取得しますか?
MarketConfigLoader MarketConfigLoader = new MarketConfigLoader(configProviderFactory.CreateDocumentProvider(Your_File_Path));
MarketConfig MarketConfig = MarketConfigLoader.load();
多分人々が驚くかもしれない場所があるでしょう。明らかに4つの構成クラスがあるので、なぜ2つの構成ローダーしかないのですか?
MarketConfig、Eggconfig、およびAppleConfigはすべて同じXML構成ファイルからロードされているため、ドキュメントオブジェクトが使用されている限り、MarketConfigLoaderを介してロードできます。
OwnerConfigは別の荷重方法であるため、別のローダーが必要です。
終わり
この記事で提案されている構成読み込みメカニズムは、実際に構成の読み込みに役立ちません。これは、DOM、SAX、およびDom4JやDigesterなどの他のオープンソースライブラリに任される必要があります。
ただし、この記事で提案されている構成読み込みメカニズムにより、構成ロードメカニズムがより柔軟で拡張しやすくなり、複数の構成読み込み方法を統合し、1つのメカニズムに統合し、独自のポイントを再生できます。
実際、一部のソフトウェアは、Struts2などの複数の異なる形式で構成ファイルから構成をロードする必要があることがよくあります。
完全な構成読み込みメカニズムがない場合、コードはより散乱し、保守性が低くなります。それは簡単に人々に血を吐かせる可能性があります。