A detailed explanation of Java configuration loading mechanism and example _java

Source: Internet
Author: User
Tags tomcat

Objective

Today almost most Java applications, such as our familiar Tomcat, struts2, Netty ... And so on the number of the software, to meet the versatility, will provide the configuration file for users to customize the function.

Even some network frameworks, such as Netty, are almost entirely driven by configuration, which we often call "microkernel architecture" software. You have to configure it as what it is.

It is what you configure it.

The most common configuration file format is XML, properties, and so on.

This article explores the most common and most commonly used scenario in load configuration, which is to map a configuration file to a Pojo object in Java.

and explore how to implement different loading methods, for example, some configurations are loaded from local XML files, and some configurations need to be loaded from local properties files,

Even more, there are configurations that need to be loaded over the network.

How to implement such a configuration loading mechanism, let us have this mechanism, will not let the load configuration code spread everywhere, and extensible, manageable.

Configuring the loader

First, we need a configuration loader, and this configuration loader can be loaded in many different ways, so we use an interface to describe it as follows:

/** * * * * @author Bean * @date January 21, 2016 11:47:12 * * * * *
 @version 1.0
 *
*/Public Interface Iconfigloader<t> {

  /**
   * Load the config typed by T * *
   @return
   * @throws confige Xception
   *
  /public T load () throws configexception;
}

However, why do we need to declare generics <T> on this interface?

Obviously, when we want to use a configuration loader, you have to tell the configuration loader what results you need to load.

For example, if you want to load a configuration and get a Appleconfig object, then you can use the interface defined above:

iconfigloader<appleconfig> loader = new appleconfigloader<appleconfig> ();
Appleconfig config = loader.load ();

So you convert the information in the configuration file into a Appleconfig object, and you get the Appleconfig object instance.

At present, seemingly as long as our appleconfigloader inside the implementation of how to load the configuration file of the specific labor, we can easily load configuration.

It can be said that, but it is not yet considered that the configuration may be loaded in different ways, such as through properties loading, through the DOM loading, through sax loading, or through some third-party open source library to load.

Therefore, in addition to configuring the loader, we need a different role to configure the provider of the loading method. For the moment, let's call it iconfigprovider.

Configure the provider of the Load method

The provider of the configuration load method can provide a way to load the configuration loader, in other words, provide an object to the configuration loader.

    1. If loaded by DOM, the provider provides a Document object to the loader.
    2. If loaded by properties, the provider provides a properties object to the loader
    3. If loaded through a Third-party class library, such as APACHE-COMMONS-DIGESTER3 (Tomcat configuration Loading), the provider provides a Digester object to the loader

The responsibility of the provider is to provide, for that matter only, the object required to configure the loader, but it does not itself participate in the configuration-loaded labor.

We use an interface Iconfigprovider to define this provider

/** * * * * @author Bean * @date January 21, 2016 11:54:28 * * * * *
 @version 1.0
 *
*/Public Interface Iconfigprovider<t> {

  /**
   * provide a config source used for loading config
   *
   * @retur N
   * @throws configexception
   *
  /Public T provide () throws configexception;
}

Why is there a <T> to declare generics here?

If you need a provider, then at least tell the provider what it should provide.

Therefore, what a provider will provide is determined by this.

At the same time, here, we can build a factory to produce a specific provider:

/**
 * * *
 @author Bean *
 @date January 21, 2016 11:56:28
 * @version 1.0 *
*/public class configproviderfactory {

  Private configproviderfactory () {
    throw new unsupportedoperationexception ("unable To initialize a factory class: "
        + getclass (). Getsimplename ());
  }

  public static iconfigprovider<document> Createdocumentprovider (String filePath) {return
    new Documentprovider (FilePath);
  }

  public static iconfigprovider<properties> Createpropertiesprovider (String filePath) {return
    new Propertiesprovider (FilePath);
  }

  public static iconfigprovider<digester> Createdigesterprovider (String filePath) {return
      new Digesterprovider (FilePath);
  }

 

Can you start implementing a specific configuration loader?

Not yet!

Here, suppose we have a configuration file called Apple.xml. And we're going to use DOM to load this apple.xml into a Appleconfig object.

Well, first I'm going to make a provider of document available to me through the provider's factory. And then get this provider, and I can call its provide method to get the document object, with the Document object, so I can start loading the configuration.

However, if you want to load Bananaconfig, pearconfig ..., the steps are the same. So we also have an abstract class that implements some of the default common behaviors.

/** * * * * @author Bean * @date January 21, 2016 11:59:19 * * * * *
 @version 1.0
 *
*/Public Abstract class Abstractconfigloader <t, u> implements iconfigloader<t>{protected

  U> provider;

  Protected Abstractconfigloader (iconfigprovider<u> provider) {
    This.provider = provider;
  }
   * * @see iconfigloader#load ()
   /
  @Override public T-
  load () throws Configexception {
    return Load (Getprovider (). provide ());

  public abstract T Load (U loadersource) throws configexception;

  Protected iconfigprovider<u> Getprovider () {return
    this.provider;
  }
}

Each configuration loader has a parameter builder that receives a provider.

Generics indicate whether I'm loading appleconfig or bananconfig, generics <U> indicates what load to load, whether it's document, properties, or anything else.

Examples of actual combat application

There is a market profile market.xml, configuration of the market of goods, there are two kinds of goods, apples and eggs, respectively.

<market>
  <apple>
    <color>red</color>
    <price>100</price>
  </apple>
  <egg>
    <weight>200</weight>
  </egg>
</market>

There is also a profile of the name of the owner of each stall, owner.properties

Port1=steve Jobs
Port2=bill Gates
Port3=kobe Bryant

We first define the following classes: Marketconfig.java

/** * * * * @author beans * @date January 21, 2016 11:03:37 * * * * *
 @version 1.0
 *
*/public class Marketconfig {

  private appleconfig appleconfig;
  Private Eggconfig eggconfig;
  Private Ownerconfig ownerconfig;

  Public Appleconfig Getappleconfig () {return
    appleconfig;
  }
  public void Setappleconfig (Appleconfig appleconfig) {
    this.appleconfig = appleconfig;
  }
  Public Eggconfig Geteggconfig () {return
    eggconfig;
  }
  public void Seteggconfig (Eggconfig eggconfig) {
    this.eggconfig = eggconfig;
  }
  Public Ownerconfig Getownerconfig () {return
    ownerconfig;
  }
  public void Setownerconfig (Ownerconfig ownerconfig) {
    this.ownerconfig = ownerconfig;
  }
}

Appleconfig.java

/** * * * * @author beans * @date January 21, 2016 11:03:45 * * * * *
 @version 1.0
 *
*/public class appleconfig {

  private int price;
  private String color;

  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 January 21, 2016 11:03:58 * * *
 @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 beans * @date January 21, 2016 11:04:06 * * * * *
 @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, owner);
  }

  public string Getownerbyportname (string portname) {return
    this.owner.get (portname);
  }

  Public map<string, String> getowners () {return
    collections.unmodifiablemap (This.owner);
  }
}

This example has two configuration loading modes, the DOM and the properties loading methods respectively.

So our provider construction plant needs to manufacture two kinds of provider provider.

And you need to define 2 configuration loaders, respectively:

Ownerconfigloader

/** * * * * @author beans * @date January 21, 2016 11:24:50 * * * * *
 @version 1.0
 *
*/public class Ownerconfigloader extends Abstractconfigloader<ownerconfig, properties>{

  /**
   * @param provider
   * *
  protected Ownerconfigloader (iconfigprovider<properties> provider) {
    super (provider);
  } 
   * * @see abstractconfigloader#load (java.lang.Object) * * *
  @Override public
  ownerconfig Load ( Properties props) throws Configexception {
    Ownerconfig ownerconfig = new Ownerconfig ();

    /**
     * Use props, set Ownerconfig attribute value
     * 
     * HERE code omitted
     /return
    ownerconfig;
  }


And then the Marketconfigloader.

Import org.w3c.dom.Document; /** * * * @author Bean * @date January 21, 2016 11:18:56 * @version 1.0 * */public class Marketconfigloader extends Ab Stractconfigloader&lt;marketconfig, document&gt; {/** * @param provider * * Protected Marketconfigloader (ICONFI
  Gprovider&lt;document&gt; provider) {super (provider); /* * * 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 (); /** * Here to process the document, and then you can get * appleconfig and EGGCONFG * * HERE code omitted * * * * * MARKETCONFIG.SETAPPLECONFIG (
    Appleconfig);

    Marketconfig.seteggconfig (Eggconfig); /** * Because the ownerconfig is required properties to load, not XML * So here is a new Ownerconfigloader, commissioned to load ownerconfig * * * Ownercon Figloader Ownerconfigloader = new Ownerconfigloader (configproviDerfactory.createpropertiesprovider (Your_file_path));

    Ownerconfig ownerconfig = Ownerconfigloader.load ();

    Marketconfig.setownerconfig (Ownerconfig);
  return marketconfig;

 }
}

Then, how do we get to marketconfig at the application level?

Marketconfigloader Marketconfigloader = new Marketconfigloader (Configproviderfactory.createdocumentprovider (YOUR_ File_path));
Marketconfig marketconfig = Marketconfigloader.load ();

There may be a place where people are surprised, there are four configuration classes, why only 2 configuration loader. Because Marketconfig, Eggconfig, and appleconfig are all loaded from the same XML configuration file, so long as a document object can be loaded through Marketconfigloader.

The ownerconfig is different loading mode, so another loader is needed.

Summarize

The configuration loading mechanism proposed in this paper can not actually help to load the configuration, this should be left to Dom,sax, as well as some other open source libraries such as dom4j,digester to do. However, the configuration loading mechanism proposed in this paper can make the configuration loading mechanism more flexible, easy to expand, and can integrate a variety of configuration loading methods, integrate into a mechanism to come in and play their own a bit.

In fact, some software often need to load the configuration from a variety of different formats at the same time, such as Struts2, and I recently in the study and was angry with the blood of a domestic open source database middleware software, if there is no complete set of configuration loading mechanism, then the code will be more fragmented, maintainability is not high Easy to make people vomit blood.

Through this article I hope you understand and master the knowledge of Java configuration loading mechanism, thank you for your support to this site!

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.