隨筆-46  評論-64  文章-2  trackbacks-0
          log4j 支持運行時修改日志的相關配置,看了一下他的source code, 用FileWatchdog這個類來做的,代碼也很簡單,通過循環在一定時間間隔讀取配置文件,如果文件變更,調用一個doOnChange()方法。

          如果自己要做一個支持運行時修改配置的系統可參考上面的做法。

          下面是一段支持運行時修改配置的系統Prototype代碼,和log4j的做法稍有不同,使用Observer模式,使其更加靈活。

          如果某個類要在系統配置修改時得到通知,則這個類要實現Observer接口,然后調用ConfigManager.getInstance().addObserver(this);

          在void update(Observable o, Object args)方法里處理相應的屬性即可。

          import?java.io.File;
          import?java.io.FileInputStream;
          import?java.io.FileOutputStream;
          import?java.io.IOException;
          import?java.io.InputStream;
          import?java.io.OutputStream;
          import?java.util.Observable;
          import?java.util.Properties;

          import?org.apache.log4j.Logger;

          import?cn.heapstack.realtimeconfig.exception.ShutdownFailureException;
          import?cn.heapstack.realtimeconfig.exception.StartupFailureException;
          import?cn.heapstack.realtimeconfig.util.FileResolver;

          /**
          ?*?<p>
          ?*?This?class?holds?all?configuration?for?the?system.?The?configuration?parameters
          ?*?are?read?from?file?at?configurable?interval.?
          ?*?
          ?*?This?class?implements?the?Singleton?pattern.
          ?*?
          ?*?Because?this?class?extends?the?<code>Observable</code>?class,?an
          ?*?<code>Observer</code>?may?register?and?get?notified?when?the?configuration
          ?*?has?changed.
          ?*?</p>
          ?*
          ?
          */

          public?final?class?DemoConfigManager?extends?Observable?implements?Runnable
          {
          ????
          private?static?DemoConfigManager?myInstance?=?new?DemoConfigManager();

          ????
          private?final?String?myName?=?"ConfigManager";

          ????
          private?static?final?Logger?myLog?=?Logger.getLogger(DemoConfigManager.class);;

          ????
          private?File?configFile?=?null;

          ????
          private?Properties?myProperties?=?new?Properties();

          ????
          private?boolean?myIsRunning?=?false;

          ????
          private?Thread?myThread?=?null;

          ????
          /**
          ?????*?Default?constructor.
          ?????
          */

          ????
          private?DemoConfigManager()
          ????
          {
          ????????
          try
          ????????
          {
          ????????????String?myConfigFile?
          =?System.getProperty("RealTimeConfigFile");
          ????????????
          if?(myConfigFile?==?null?||?"".equals(myConfigFile))
          ????????????
          {
          ????????????????myConfigFile?
          =?"conf/RealTimeConfig.conf";
          ????????????}

          ????????????configFile?
          =?FileResolver.loadFile(myConfigFile);
          ????????????InputStream?is?
          =?new?FileInputStream(configFile);
          ????????????myProperties.load(is);
          ????????????is.close();
          ????????}

          ????????
          catch?(IOException?ex)
          ????????
          {
          ????????????System.err.println(
          "Error?reading?RealTimeConfig?configuration?file.?Will?now?exit?RealTimeConfig:?"?+?ex);
          ????????????System.exit(
          -1);
          ????????}

          ????}


          ????
          /**
          ?????*?Return?the?name?of?this?subsystem.
          ?????
          */

          ????
          public?String?getName()
          ????
          {
          ????????
          return?myName;
          ????}


          ????
          /**
          ?????*?Get?the?singleton?instance?of?this?class.
          ?????*?
          ?????*?
          @return?The?singleton?instance.
          ?????
          */

          ????
          public?static?DemoConfigManager?getInstance()
          ????
          {
          ????????
          return?myInstance;
          ????}


          ????
          /**
          ?????*?Loads?the?configuration?from?file.
          ?????*?
          ?????*?If?find?the?configuration?file?changed,?notify?the?observers
          ?????*?
          ?????*?
          @throws?IOException
          ?????*?????????????If?unable?to?open?and?read?configuration?file.
          ?????
          */

          ????
          private?void?load()?throws?IOException
          ????
          {
          ????????InputStream?is?
          =?(InputStream)?new?FileInputStream(configFile);
          ????????Properties?aFromFileProp?
          =?new?Properties();
          ????????aFromFileProp.load(is);

          ????????
          //?Check?if?the?properties?in?file?has?been?updated?compared?to?the?stored?properties.
          ????????if?(!aFromFileProp.toString().equals(myProperties.toString()))
          ????????
          {
          ????????????myProperties?
          =?aFromFileProp;
          ????????????
          this.setChanged();
          ????????????
          this.notifyObservers();
          ????????}

          ????????is.close();
          ????}


          ????
          /**
          ?????*?The?run?method?of?the?ConfigManager?thread.?It?will?read?the
          ?????*?configuration?from?file?every?30?seconds.
          ?????
          */

          ????
          public?void?run()
          ????
          {
          ????????
          while?(myIsRunning)
          ????????
          {
          ????????????
          int?interval?=?30;
          ????????????
          try
          ????????????
          {
          ????????????????interval?
          =?Integer.parseInt(myProperties.getProperty("ReadConfigInterval"));
          ????????????}

          ????????????
          catch?(NumberFormatException?ex)
          ????????????
          {
          ????????????????myLog.info(
          ????????????????????????
          "Error?reading?ReadConfigInterval?config?parameter.?Using?default?value("+interval+").");
          ????????????}


          ????????????
          try
          ????????????
          {
          ????????????????Thread.sleep(interval?
          *?1000);
          ????????????????load();
          ????????????}

          ????????????
          catch?(IOException?ex)
          ????????????
          {
          ????????????????myLog.info(?
          "IO?error?while?trying?to?load?config?file:?"
          ????????????????????????
          +?ex.getMessage());
          ????????????}

          ????????????
          catch?(InterruptedException?ex)
          ????????????
          {
          ????????????????
          ????????????}

          ????????}

          ????}


          ????
          /**
          ?????*?Save?the?configuration?to?file.?Existing?configuration?data?will?be?over
          ?????*?written.
          ?????*?
          ?????*?
          @throws?IOException
          ?????*?????????????If?unable?to?open?and?write?to?file.
          ?????
          */

          ????
          public?synchronized?void?save()?throws?IOException
          ????
          {
          ????????OutputStream?os?
          =?(OutputStream)?new?FileOutputStream(configFile);
          ????????myProperties.store(os,?
          "RealTimeConfig");
          ????????os.close();
          ????}


          ????
          /**
          ?????*?Get?a?configuration?value?of?a?specified?parameter?(key).
          ?????*?
          ?????*?
          @param?theKey
          ?????*????????????The?name?of?the?parameter?to?fetch?a?value?from.
          ?????*?
          ?????*?
          @return?The?configuration?value?for?the?specified?key.
          ?????
          */

          ????
          public?synchronized?String?get(String?theKey)
          ????
          {
          ????????
          return?myProperties.getProperty(theKey);
          ????}


          ????
          /**
          ?????*?Set?a?configuration?value?of?a?specified?parameter?(key).
          ?????*?
          ?????*?
          @param?theKey
          ?????*????????????The?name?of?the?parameter?to?set.
          ?????*?
          ?????*?
          @param?theValue
          ?????*????????????The?value?of?the?parameter?to?set.
          ?????
          */

          ????
          public?synchronized?void?set(String?theKey,?String?theValue)
          ????
          {
          ????????myProperties.setProperty(theKey,?theValue);
          ????}


          ????
          /**
          ?????*?Get?all?parameters?contained?in?the?ConfigManager.
          ?????*?
          ?????*?
          @return?A?Properties?object?containing?all?configuration?parameters?and
          ?????*?????????their?value.
          ?????
          */

          ????
          public?synchronized?Properties?getProperties()
          ????
          {
          ????????
          return?myProperties;
          ????}


          ????
          /**
          ?????*?Start?the?ConfigManager?and?read?configuration?from?file.?From?now?on?the
          ?????*?configuration?will?be?read?from?file?at?a?configurable?interval,?default
          ?????*?30?seconds.
          ?????
          */

          ????
          public?synchronized?void?startup()?throws?StartupFailureException
          ????
          {
          ????????
          if?(myIsRunning)
          ????????
          {
          ????????????
          throw?new?StartupFailureException("Subsystem?is?already?running!");
          ????????}


          ????????myIsRunning?
          =?true;

          ????????myThread?
          =?new?Thread(this,?this.getName());
          ????????myThread.start();
          ????}


          ????
          /**
          ?????*?Shuts?down?the?ConfigManager.
          ?????*?
          ?????*?
          @param?theGracefulShutdownMode
          ?????*????????????<code>true</code>?if?shut?down?should?be?graceful,
          ?????*????????????<code>false</code>?otherwise.
          ?????
          */

          ????
          public?synchronized?void?shutdown(boolean?theGracefulShutdownMode)
          ????????????
          throws?ShutdownFailureException
          ????
          {
          ????????
          if?(!this.isRunning())
          ????????
          {
          ????????????
          throw?new?ShutdownFailureException("Subsystem?is?already?stopped!");
          ????????}


          ????????myIsRunning?
          =?false;
          ????????
          try
          ????????
          {
          ????????????myThread.interrupt();
          ????????????myThread.join(
          1?*?60?*?1000);
          ????????}

          ????????
          catch?(InterruptedException?ex)
          ????????
          {
          ????????}

          ????????
          catch?(SecurityException?ex)
          ????????
          {
          ????????}


          ????????myThread?
          =?null;
          ????}


          ????
          /**
          ?????*?Checks?if?the?ConfigManager?is?alive.
          ?????*?
          ?????*?
          @return?<code>true</code>?if?alive,?otherwise?<code>false</code>.
          ?????
          */

          ????
          public?boolean?isRunning()
          ????
          {
          ????????
          return?(myThread?!=?null?&&?myThread.isAlive()?&&?myIsRunning);
          ????}

          }

          posted on 2008-09-04 14:49 jht 閱讀(1331) 評論(0)  編輯  收藏 所屬分類: J2SE
          主站蜘蛛池模板: 北宁市| 新巴尔虎左旗| 多伦县| 南雄市| 桦川县| 彰化市| 邢台市| 宝鸡市| 旺苍县| 左云县| 金乡县| 辽阳县| 泽州县| 抚顺市| 海城市| 兰州市| 南皮县| 霍林郭勒市| 沙雅县| 东方市| 安阳县| 廊坊市| 百色市| 崇仁县| 遵义市| 九龙坡区| 昌乐县| 枣强县| 贵定县| 台山市| 油尖旺区| 开封市| 凯里市| 黎城县| 文登市| 台江县| 大英县| 长武县| 台南市| 斗六市| 沙田区|