Предисловие
В настоящее время почти большинство Java -приложений, такие как Tomcat, Struts2, Netty и т. Д., С которыми мы знакомы, не можем их считать,
Чтобы соответствовать универсальности, для пользователей предоставляются файлы конфигурации для настройки функций.
Есть даже некоторые сетевые структуры, такие как Netty, которые практически полностью настроены, и мы обычно называем такую программную архитектуру микрокера ».
Что бы вы это ни настроили, это то, что есть.
Это то, что вы настраиваете, чтобы быть.
Наиболее распространенными форматами файлов конфигурации являются XML, свойства и другие файлы.
В этой статье обсуждается наиболее распространенный и распространенный сценарий при загрузке конфигураций, который состоит в том, чтобы составить карту файла конфигурации в объект POJO в Java.
И обсудить, как реализовать разные способы загрузки. Например, некоторые конфигурации загружаются из локальных файлов XML, в то время как некоторые конфигурации должны быть загружены из файлов локальных свойств, и, более того, некоторые конфигурации должны быть загружены через сеть.
Как реализовать такой механизм загрузки конфигурации, чтобы после того, как у нас есть этот механизм, конфигурация загрузки кода не была распространялась повсюду, и она масштабируется и управляемо.
Настройте загрузчик
Во -первых, нам нужен загрузчик конфигурации, и этот загрузчик конфигурации может иметь много различных методов загрузки. Поэтому мы используем интерфейс, чтобы описать его следующим образом:
/** * * * * @author bean * @date 21 января 2016 г. в 11:47:12 AM * @version 1.0 * *//public interface Iconfiglogray <t> {/** * Загрузить конфигурацию T * * @return * @Throws configException */public t Load () Throhs ConfigExcept Но почему нам нужно объявлять генерики <T> на этом интерфейсе?
Очевидно, что когда мы хотим использовать загрузчик конфигурации, вы должны сообщить этот загрузчик конфигурации, какие результаты вам нужно получить после загрузки.
Например, если вы хотите загрузить конфигурацию и получить объект AppleConfig, вы можете использовать интерфейс, определенный выше:
IconfigLoader <AppleConfig> loader = new AppleConfigGloader <AppleConfig> (); AppleConfig config = loader.load ();
Таким образом, вы конвертируете информацию в файле конфигурации в объект AppleConfig, и вы можете получить этот экземпляр объекта AppleConfig.
До сих пор кажется, что до тех пор, пока наш AppleConfigRoader реализует конкретный труд, как загружать файлы конфигурации, мы можем легко загрузить конфигурации.
Можно сказать, что, но не то, что конфигурация может быть загружена различными способами, такими как загрузка с помощью свойств, DOM, SAX или загрузка через некоторые сторонние библиотеки с открытым исходным кодом.
Поэтому, в дополнение к настройке загрузчика, нам также нужна другая роль, поставщик настройки метода загрузки. Назовем это IconfigProvider.
Настройка поставщика методов загрузки
Поставщик методов загрузки конфигурации может предоставить метод загрузки для загрузчика конфигурации, другими словами, предоставить объект для загрузчика конфигурации.
Если загружен через DOM, поставщик предоставляет объект документа для загрузчика.
При загрузке через свойства поставщик предоставляет объект свойств погрузчику. Если загружено методом, предоставленным сторонней библиотекой классов, такой как Apache-Commons-Digester3 (загрузка конфигурации Tomcat), поставщик предоставляет объект Digester для поставщика погрузчика, чтобы предоставить его, это все, только предоставляя объекты, необходимые для настройки погрузчика, но он сам не участвует в труде настройки загрузки.
Мы используем интерфейс IconfigProvider для определения этого поставщика
/** * * * * @author bean * @date 21 января 2016 г. в 11:54:28 * @version 1.0 * *//public inconfigprovider <t> {/** * Предоставляет источник конфигурации, используемый для загрузки конфигурации * * @return * @Throws ConfigExcept Почему здесь есть дженерики?
Если вам нужен поставщик, то, по крайней мере, вы должны рассказать поставщику, что он должен предоставить.
Поэтому то, что предоставит поставщик, определяется этим.
В то же время мы можем сначала построить фабрику и позволить ей производить конкретных поставщиков:
/** * * * * @author bean * @date 21 января 2016 г. в 11:56:28 AM * @version 1.0 * */public Class ConfigProviderFactory {private ConfigProviderFactory () {Throw New UnsupportedOperationException ("Невозможно инициализировать заводский класс:" + getClass (). getSiMplename (); } public Static IconfigProvider <comoction> createcumentProvider (String filePath) {return New DocumentProvider (filePath); } public static iconfigProvider <properties> createPropertiesProvider (String filePath) {return New PropertiesProvider (filePath); } public static iconfigProvider <Gigester> cenectiGesterprovider (String filePath) {return new DigesterProvider (filePath); }}Можете ли вы начать реализацию конкретного загрузчика конфигурации?
Еще не хорошо!
На этом этапе, предположим, у нас есть файл конфигурации с именем Apple.xml. И нам нужно загрузить это Apple.xml в объект AppleConfig через DOM.
Итак, во -первых, я хочу создать поставщика, который может предоставить документ через фабрику поставщика. Затем я получаю этого поставщика, и я могу вызвать его метод предоставления, чтобы получить объект документа.
С объектом документа я могу начать загружать конфигурацию.
Однако, если вы хотите загрузить Bananaconfig, Pearconfig ......, шаги одинаковы. Поэтому нам также нужен абстрактный класс для реализации некоторого общего поведения по умолчанию.
/** * * * * @author bean * @date 21 января 2016 года в 11:59:19 * @version 1.0 * */public abstract class AbstractConfigerer <T, u> реализует ICONFIGLERER <T> {Защищенный ICONFIGPIGPIDER <U> Provider; Protected AbstractConfigRoader (iconfigProvider <u> провайдер) {this.provider = поставщик; } / * * @see iconfigloader#load () * / @override public t loge () Throws ConfigException {return Load (getProvider (). предоставление ()); } public Abstract T Load (U LoaderSource) Throws ConfigException; Защищенный iconfigProvider <u> getProvider () {return this.provider; }}Каждый загрузчик конфигурации имеет конструктор параметров, который получает поставщика.
Generic указывает, хочу ли я загрузить AppleConfig или Bananconfig. Общий <U> указывает, какой способ загрузки загрузки - это документ, свойства или что -то еще.
Практические примеры применения
Существует рынок файлов конфигурации овощного рынка. XML, который настраивает продукты рынка овощей, включая два продукта, а именно яблоки и яйца.
<Market> <pple> <solor> red </color> <цена> 100 </price> </apple> <яиц> <вес> 200 </вес> </egg> </market>
Существует также файл конфигурации для имен боссов в каждом кабине, владелец.
Порт1 = Стив Джобспорт2 = Билл Гейтспорт3 = Коби Брайант
Давайте сначала определим следующие классы:
MarketConfig.java
/** * * * * @author bean * @date 21 января 2016 года в 23:03:37 * @version 1.0 * */public Class MarketConfig {private AppleConfig AppleConfig; Частный EggConfig EggConfig; Private OwnerConfig OwnerErconfig; 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 bean * @date 21 января 2016 года в 11:03:45 * @version 1.0 * */public class AppleConfig {private int price; Частный цвет струны; public void setprice (int price) {this.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 21 января 2016 года в 11:03:58 * @version 1.0 * */public class EggConfig {private int wews; public void легкий вес (int Weew) {this.weight = Weew; } public int get -weight () {return this.weight; }} OwnerConfig.java
/** * * * * @author bean * @date 21 января 2016 года в 11:04:06 * @version 1.0 * */public class ownerconfig {private map <string, string> akens = new hashmap <string, string> (); public void Addowner (String portname, String владелец) {this.owner.put (portname, владелец); } public String getOwnerByportName (String portName) {return this.owner.get (portname); } public map <string, string> getOwners () {return collections.unmodifiablemap (this.owner); }} Для этого примера существуют два метода загрузки конфигурации, а именно методы загрузки DOM и свойства.
Таким образом, нашим провайдерам необходимо создавать фабрики с двумя поставщиками.
И два конфигурационных загрузчика необходимо определить, а именно:
OwnerConfigGulder
/** * * * * @author bean * @date 21 января 2016 г. в 11:24:50 * @version 1.0 * */public Class ownerconfigloder расширяет AbstractConfigerer <howererconfig, свойства> {/** * @param Provider */protected ownerconfigguder (iconfigprovider <perperties> {Provider) {Provider) {Provider); } / * * @See AbstractCONFIGLIGE#LOAD (java.lang.object) * / @@override public owerErconfig Load (Properties props) Throws configException {helyerconfig ownerconfig = new ownerconfig (); / ** * Используйте реквизиты для установки значения свойства OwnerConfig * * Код здесь опущен */ return ownerConfig; }}Тогда есть MarketConfigerler
Import org.w3c.dom.document;/** * * * @author bean * @date 21 января 2016 г. в 11:18:56 * @version 1.0 * *//public Class MarketConfiggloder extrableConfigGulater <MarketConfig, документ> {/** * @Param Provectuder) (iconfrovider <compticle) (iconfrovider <comomefit> @provider) (iconfrovider <Документ> @param Proveculder (iconfrovider <Документ> @Param Provecloader (iconfrovider). } / * * AbstractConfigLogler#LOAD (java.lang.object) * / @@override public MarketConfig Load (документ документ) THRES ConfigException {MarketConfig MarketConfig = new MarketConfig (); AppleConfig AppleConfig = new ApplEconfig (); EggConfig EggConfig = новый EggConfig (); / ** * Обработайте документ здесь, и затем вы можете получить * AppleConfig и EggConfg * * Код здесь опущен */ MarketConfig.SetAppleConfig (ApplEconfig); MarketConfig.seteggConfig (EggConfig); / ** * Поскольку OwnerConfig требует загрузки свойств, это не XML *, поэтому нам нужно создать новый OwnerConFigRoader и делегировать его для загрузки OwnerConfig *// ownerConfigGloader OwnerConFigRoader = new OwnerConfigRulter (configVoviderFactory.createPerpertiesprovider (your_file_path); OwnerConfig OwnerErconFig = OwnerConFigGloader.Load (); MarketConfig.SetownerConfig (OwnerConfig); return MarketConfig; }}Тогда как мы можем получить MarketConfig на уровне приложения?
MarketConfigRoader MarketConfigGloader = New MarketConfigerler (configProviderFactory.createdocumentProvider (your_file_path));
MarketConfig MarketConfig = MarketConfigGloader.Load ();
Может быть, есть место, где люди могут быть удивлены. Очевидно, есть четыре класса конфигурации, так почему есть только два загрузки конфигурации?
Поскольку MarketConfig, EggConfig и AppleConfig загружаются из одного и того же файла конфигурации XML, если используется объект документа, его можно загрузить через MarketConfigerler.
OwnerConfig - это другой метод загрузки, поэтому необходим другой погрузчик.
конец
Механизм загрузки конфигурации, предложенный в этой статье, не может помочь загрузить конфигурацию. Это должно быть оставлено для DOM, SAX и некоторых других библиотек с открытым исходным кодом, таких как DOM4J и Digester.
Тем не менее, механизм загрузки конфигурации, предложенный в этой статье, может сделать механизм загрузки конфигурации более гибким и простым в расширении, и может интегрировать несколько методов загрузки конфигурации, интегрировать их в один механизм и воспроизводить свои собственные точки.
Фактически, некоторое программное обеспечение часто необходимо загружать конфигурации из файлов конфигурации в разных разных форматах одновременно, таких как Struts2, и домашнее программное обеспечение для промежуточного программного обеспечения с открытым исходным кодом, которое я недавно изучал и рвал кровь.
Если нет полного механизма загрузки конфигурации, код будет более разбросанным и менее обслуживаемым. Это может легко заставить людей рвать кровь.