Vincent

          Vicent's blog
          隨筆 - 74, 文章 - 0, 評論 - 5, 引用 - 0
          數據加載中……

          Spring技巧之活用FactoryBean

          Spring中有兩種類型的Bean,一種是普通Bean,另一種是工廠Bean,即FactoryBean。工廠Bean跟普通Bean不同,其返回的對象不是指定類的一個實例,其返回的是該工廠Bean的getObject方法所返回的對象。在Spring框架內部,AOP相關的功能及事務處理中,很多地方使用到工廠Bean,本文簡單分析工廠Bean的用法。
          首先回顧一下普通Bean,普通的Bean直接返回指定類(配置中的class屬性的值)的一個實例,如下面的bean1將返回一個String字符串:
          <bean?name="bean1"?class="java.lang.String">
          ?
          <constructor-arg?value="我是字符串!"?/>
          ?
          </bean>?

          下面,看看一個簡單的工廠Bean:
          import?java.util.Date;
          import?org.springframework.beans.factory.FactoryBean;
          public?class?FactoryBeanDemo?implements?FactoryBean?{
          ?
          private?String?name;
          ?
          public?void?setName(String?name)
          ?{
          ??
          this.name=name;
          ?}
          ?
          public?Object?getObject()?throws?Exception?{
          ??
          if("date".equals(name))return?new?Date();
          ??
          else?return?new?String("這是一個字符串!");
          ?}
          ?
          public?Class?getObjectType()?{??
          ??
          return?"date".equals(name)?Date.class:String.class;
          ?}
          ?
          public?boolean?isSingleton()?{??
          ??
          return?false;
          ?}
          }

          下面看這個工廠Bean的配置:
          <bean?name="myFactoryBean"?class="springroad.deomo.chap4.FactoryBeanDemo"/>
          <bean?name="myFactoryBean1"?class="springroad.deomo.chap4.FactoryBeanDemo"><property?name="name"?value="date"/></bean>

          下面是測試代碼:
          Resource?res=new?ClassPathResource("springroad/deomo/chap4/demo-bean.xml");
          BeanFactory?factory
          =new?XmlBeanFactory(res);
          System.out.println(factory.getBean(
          "myFactoryBean").getClass());
          System.out.println(factory.getBean(
          "myFactoryBean1").getClass());


          輸出結果:
          class?java.lang.String
          class?java.util.Date


          由此可見,通過使用FactoryBean,我們可以得到不同類型的對象實例。這也就是我們在AOP中通過設置calss為 ProxyFactoryBean可以返回不同類型的業務對象的原理。在實際應用中若能靈活使用FactoryBean,則可以給應用程序增加很多的魔幻功能。

          一個小竅門:
            FactoryBean還藏有一個技巧,也就是在我們實際需要返回FactoryBean實例時,應該怎么辦。也就是我們在應用程序中需要通過容器得到一個FactoryBean。此時,需要使用特殊的方式,即在bean的名稱前加上一個特殊符號“&”即可。
            如,下面的代碼:
          System.out.println(factory.getBean("&myFactoryBean").getClass());
          ?System.out.println(factory.getBean(
          "&myFactoryBean1").getClass());

          輸出的結果將會是:
          class ?springroad.deomo.chap4.FactoryBeanDemo
          class ?springroad.deomo.chap4.FactoryBeanDemo?

          posted @ 2006-08-22 09:52 Binary 閱讀(270) | 評論 (0)編輯 收藏

          Spring2.0中新的Bean類型實現原理

          我們知道,在Spring2.0中,除了singleton及prototype兩種類型的Bean以外。默認情況下還增加了request、 session及global?session三種類型的Bean,增加的三種類型的Bean主要應用于Web應用程序中。本文不打算分析三種類型的 Bean的用法,只是簡單分析框架的實現原理。
            Spring2.0中新增了一個用來表示Bean范圍的Scope接口
            public?interface?Scope?{
            Object?get(String?name,?ObjectFactory?objectFactory);
          //根據名稱及創建工廠得到一個Bean實例
            Object?remove(String?name);//刪除一個指定名稱的Bean
            }


            在容器ConfigurableBeanFactory接口中定義了Bean工廠有關Scope注冊的相關方法,使得可往Bean工廠中加入新類型的Bean。
            public?interface?ConfigurableBeanFactory?extends?HierarchicalBeanFactory,
            
          void?registerScope(String?scopeName,?Scope?scope);//往Bean工廠中添加一個新的范圍(默認只有兩種范圍:singleton及prototype)
            void?destroyScopedBean(String?beanName);//銷毀B?ean工廠中范圍Bean
            }


            在AbstractFactoryBean的getBean方法中實現了對特定Scope?Bean支持,核心代碼摘要:

          ????String?scopeName?=?mergedBeanDefinition.getScope();//取得當前Bean的范圍,也即在定義中的scope=”request”的部分。
          ????Scope?scope?=?(Scope)?this.scopes.get(scopeName);//得到Bean工廠中的范圍處理器
          ????if?(scope?==?null)?{
          ?????
          throw?new?IllegalStateException("No?Scope?registered?for?scope?'"?+?scopeName?+?"'");
          ????}
          ????
          try?{
          //使用scope.get(beanName,ObjectFactory)從指定的范圍中得到或創建Bean實例
          ?????Object?scopedInstance?=?scope.get(beanName,?new?ObjectFactory()?{
          ??????
          public?Object?getObject()?throws?BeansException?{
          ???????beforePrototypeCreation(beanName);
          //前攔截
          ???????try?{
          ????????
          return?createBean(beanName,?mergedBeanDefinition,?args);//調用子類的createBean實現真正的Bean創建工作
          ???????}
          ???????
          finally?{
          ????????afterPrototypeCreation(beanName);
          //后攔截
          ???????}
          ??????}
          ?????});
          ?????bean?
          =?getObjectForBeanInstance(scopedInstance,?name,?mergedBeanDefinition);//返回正確類型的Bean實例
          ????}
          ????
          catch?(IllegalStateException?ex)?{
          ?????
          throw?new?BeanCreationException(beanName,?"Scope?'"?+?scopeName?+?"'?is?not?active",?ex);
          ????}


            默認情況下,低層的Bean工廠中只支持singleton及prototype兩種類型的Bean。當把scope設置成request及 session時將會出現不能正確識別Scope的錯誤。這是因為普通的Bean工廠都沒有注冊新的Scope。只有在 WebApplicationContext中注冊才注冊了新類型的Bean。
            下面看實現注冊Scope的代碼:
            在WebApplicationContext中定義常量
          public?interface?WebApplicationContext?extends?ApplicationContext?{
            String?SCOPE_REQUEST?
          =?"request";
            String?SCOPE_SESSION?
          =?"session";
          ?????????String?SCOPE_GLOBAL_SESSION?
          =?"globalSession";
          }


            然后在所有類型的Web應用上下文的實現中,都在Bean工廠的攔載過程中通過postProcessBeanFactory方法來注冊新類型 Scope,如GenericWebApplicationContext、StaticWebApplicationContext、
          AbstractRefreshableWebApplicationContext等WebApplication應用上下文實現中。
            
          protected?void?postProcessBeanFactory(ConfigurableListableBeanFactory?beanFactory)?{
            ??beanFactory.registerScope(SCOPE_REQUEST,?
          new?RequestScope());//注冊request類型的Bean
            ??beanFactory.registerScope(SCOPE_SESSION,?new?SessionScope(false));//注冊session類型的Bean
            ??beanFactory.registerScope(SCOPE_GLOBAL_SESSION,?new?SessionScope(true));//注冊glogalsession  的Bean
          }


            結合上面的代碼,現在應該明白為什么只有在Web應用上下文中才能使用新增加三種類型的Bean了吧。當然,由于有了Scope,我們也可以非常輕松的實現我們自己的Scope,增加新用戶自定義類型的Bean,然后設計出一個適合我們自己的Bean工廠。

          posted @ 2006-08-22 09:49 Binary 閱讀(271) | 評論 (0)編輯 收藏

          MYSQL的master/slave數據同步配置

          我的測試環境.基本上數據是瞬間同步,希望對大家有幫助


          redhat 9.0
          mysql3.23.57



          mysql數據同步備份


          A服務器: 192.168.1.2 主服務器master
          B服務器: 192.168.1.3 副服務器slave



          A服務器設置


          #mysql ?u root ?p
          mysql>GRANT FILE ON *.* TO backup@192.168.1.3 IDENTIFIED BY ‘1234’;
          mysql>\exit


          上面是Master開放一個賬號backup密碼1234給IP:192.168.1.3有檔案處理的權限



          mysqladmin ?u root ?p shutdown


          備份Master所有數據庫..通常都用tar指令.
          #tar ?cvf /tmp/mysql.tar /var/lib/mysql
          注意:tar的時候,MySQL是要在stop情況下


          在A機器上修改/etc/my.cnf
          在[mysqld]區段內加入參數
          log-bin
          server-id=1
          sql-bin-update-same
          binlog-do-db=vbb


          重啟A服務器mysql


          此時因為有加入log-bin參數,因此開始有index產生了,在/var/lib/mysql目錄下有.index檔案紀錄數據庫的異動log.



          B服務器設置


          設定/etc/my.cnf
          在[mysqld]區段加入


          master-host=192.168.1.2
          master-user=backup
          master-password=1234
          master-port=3306
          server-id=2
          master-connect-retry=60 預設重試間隔60秒
          replicate-do-db=vbb 告訴slave只做vbb數據庫的更新
          log-slave-updates



          將A上的mysql.tar copy到B上
          用ftp傳B的/tmp
          9.解壓縮
          #cd /var/lib/



          狀況測試
          1.A跟B網絡及服務都正常情況下,由A端變化數據后,到B端瀏覽數據,檢視是否有進行replication?!
          2.模擬B當機,或是B不一定需要一直跟A有連接.
          將由A端變化數據后,到B端瀏覽數據,B點應該是沒有數據變化的



          #tar xvf /tmp/mysql-snapshot.tar
          #chown ?R mysql:mysql mysql


          1重啟B服務器的mysql


          這時在/var/lib/mysql目錄會出現master.info,此檔案紀錄了Master MySQL server的信息.


          ?


          狀況測試
          1.A跟B網絡及服務都正常情況下,由A端變化數據后,到B端瀏覽數據,檢視是否有進行replication?!
          2.模擬B當機,或是B不一定需要一直跟A有連接.
          將由A端變化數據后,到B端瀏覽數據,B點應該是沒有數據變化的

          posted @ 2006-08-22 09:43 Binary 閱讀(229) | 評論 (0)編輯 收藏

          加大MySQL的最大連接數

          mysql的最大連接數默認是100, 這個數值對于并發連接很多的數據庫應用是遠遠不夠的,當連接請求大于默認連接數后,就會出現無法連接數據庫的錯誤,因此我們需要把它適當調大一些,
          有兩種辦法可以修改最大連接數,一種是修改safe_mysqld,另一種是直接修改原代碼并重新編譯。下面我們就分別介紹這兩種方法:

          1.修改safe_mysqld
          找到safe_mysqld編輯它,找到mysqld啟動的那兩行,在后面加上參數 :

          -O max_connections=1000


          例如 :(其中前面有---的是原來的內容,而+++是修改過以后的)
          --- safe_mysqld.orig Mon Sep 25 09:34:01 2000
          +++ safe_mysqld Sun Sep 24 16:56:46 2000
          @@ -109,10 +109,10 @@
          if test "$#" -eq 0
          then
          nohup $ledir/mysqld --basedir=$MY_BASEDIR_VERSION --datadir=$DATADIR \
          - --skip-locking >> $err_log 2>&1
          + --skip-locking -O max_connections=1000 >> $err_log 2>&1
          else
          nohup $ledir/mysqld --basedir=$MY_BASEDIR_VERSION --datadir=$DATADIR \
          - --skip-locking "$@" >> $err_log 2>&1
          + --skip-locking "$@" -O max_connections=1000 >> $err_log 2>&1
          fi
          if test ! -f $pid_file # This is removed if normal shutdown
          then
          然后關閉mysql重啟它,用
          /mysqladmin所在路徑/mysqladmin -uroot -p variables
          輸入root數據庫賬號的密碼后可看到
          | max_connections | 1000 |
          即新改動已經生效。

          2.修改原代碼

          解開MySQL的原代碼,進入里面的sql目錄修改mysqld.cc找到下面一行:

          { "max_connections", (long*) &max_connections,1000,1,16384,0,1},

          把它改為:

          { "max_connections", (long*) &max_connections,1000,1,16384,0,1},

          存盤退出,然后./configure make;make install可以獲得同樣的效果。

          ?

          posted @ 2006-08-22 09:42 Binary 閱讀(196) | 評論 (0)編輯 收藏

          僅列出標題
          共8頁: 上一頁 1 2 3 4 5 6 7 8 
          主站蜘蛛池模板: 全南县| 梁山县| 清镇市| 广西| 广德县| 安泽县| 隆子县| 鄂托克前旗| 巴南区| 襄汾县| 遵化市| 盱眙县| 靖江市| 兴国县| 玉环县| 七台河市| 弋阳县| 汤阴县| 三明市| 吉安县| 普洱| 万盛区| 崇阳县| 西丰县| 伊宁县| 扎兰屯市| 普安县| 扎赉特旗| 北辰区| 中江县| 彩票| 淄博市| 越西县| 淳化县| 新巴尔虎左旗| 广州市| 县级市| 聂拉木县| 太仓市| 太谷县| 克什克腾旗|