隨筆-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
          Locations of visitors to this page
          讀書:
          《JAVA與模式》閻宏
          《精通正則表達式》
          《Perl語言入門》
          《J2EE Development without EJB》
          BlogJava-季浩的Blog
          100.0%男性傾向,0.0%女性傾向
          評點:您的文風冷靜而鎮定,言語間展現出強悍的思辨能力與恢宏的胸襟,一個男子漢的陽剛形象躍然紙上。
          yodao | 博客男女

          很不錯的網站,在線沖手機費
          <2008年9月>
          31123456
          78910111213
          14151617181920
          21222324252627
          2829301234
          567891011

          常用鏈接

          留言簿(2)

          隨筆分類

          隨筆檔案

          文章檔案

          我的BLOG

          搜索

          •  

          積分與排名

          • 積分 - 104312
          • 排名 - 560

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 额尔古纳市| 五峰| 香港 | 绥棱县| 乌兰浩特市| 托克托县| 麻阳| 南京市| 聂荣县| 南召县| 普宁市| 张北县| 葫芦岛市| 福鼎市| 五莲县| 潜江市| 托克逊县| 历史| 莎车县| 博野县| 金秀| 习水县| 郑州市| 襄城县| 通河县| 额尔古纳市| 城市| 宾阳县| 秦皇岛市| 弥渡县| 北票市| 石屏县| 永安市| 贵南县| 天台县| 新宁县| 城口县| 曲麻莱县| 山东| 藁城市| 岳西县|