隨筆 - 8, 文章 - 0, 評論 - 4, 引用 - 0
          數據加載中……

          2008年3月18日

          Java靜態代理和動態代理

          網上和bolg上相關例子不少,今天自己動手寫了個例子作為學習筆記。
          首先java代理分為靜態代理和動態代理,動態代理中java提供的動態代理需要動態代理一個inteface,如果沒有inteface則需要使用實現cglib提供的接口。
          下面例子只實現動態代理
          public class MyProxy implements InvocationHandler{
              
              
          static Object proxyObj = null;    
              
              
          public static Object getInstance(Object obj){
                  proxyObj
          = obj;
                  
          return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), new MyProxy());
              }

              
              
          public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                  System.out.println(
          "使用代理..");
                  
          return method.invoke(proxyObj, args);
              }

          }

          實現方式
          public static void main(String[] args) {
                  ILeaveService service 
          = (ILeaveService)MyProxy.getInstance(new LeaveServiceImpl());
                  
          try {
                      service.listBizObjByHql(
          "");
                  }

                  
          catch (ServiceException e) {
                      e.printStackTrace();
                  }

              }

          打印出:
          使用代理..
          query Hql..
          使用Cglib
          public class Test2 implements MethodInterceptor {
                  
              
              
          public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
                  System.out.println(
          "cglib proxy");
                  
          return methodProxy.invokeSuper(obj, args);
              }

              
          }

          實現
          public static void main(String[] args) {
                  Enhancer enhancer 
          = new  Enhancer();
                  enhancer.setSuperclass(Test3.class);
                  enhancer.setCallback(new Test2());        

                  Test3 test 
          = (Test3)enhancer.create();
                  test.prinInfo(
          "p.");
              }
          輸出
          cglib proxy
          p.
          過濾器
          public class Test4 implements CallbackFilter{

              
          public int accept(Method method) {
                  
          if(method.getName().equals("method1")){
                      
          return 1;
                  }
          else if(method.getName().equals("method2")){
                      
          return 0;
                  }

                  
          return 0;
              }

              
          }
          只有返回0的才執行(cglib中的NoOp.INSTANCE就是一個空的攔截器
              public static void main(String[] args) {        
                  Callback [] callbacks 
          = new Callback[]{new Test2(),NoOp.INSTANCE};
                  Enhancer enhancer 
          = new Enhancer();
                  enhancer.setSuperclass(Test3.
          class);
                  enhancer.setCallbacks(callbacks);
                  enhancer.setCallbackFilter(
          new Test4());
                  Test3 test3 
          = (Test3)enhancer.create();
                  test3.method1();
                  test3.method2();
              }

              
          }

          執行結果
          method1
          cglib proxy
          method2

          posted @ 2009-02-18 16:52 Pitey 閱讀(495) | 評論 (0)編輯 收藏

          轉:Message Driven POJO

          作者:江南白衣 
            
              一直希望那些J字頭的協議能有幾個提前告老還鄉的,好減輕一下我們的負擔,特別是這WebService滿天飛的時代。但似乎還有很久都輪不到JMS的消失:

              1.因為
              1.它是《Effective Enterprise Java》的一個實踐。 
              可以把不影響用戶執行結果又比較耗時的任務(比如發郵件通知管理員)異步的扔給JMS 服務端去做,而盡快的把屏幕返還給用戶。
              而且服務端能夠多線程排隊響應--高并發的請求。

              2. 可以在Java世界里達到最高的解耦。
                 對比WebService,JMS的客戶端與服務端無需直連,甚至無需知曉對方是誰、在哪里、有多少人,只要對流過的信息作響應就行了。對牽一發動全身的企業應用來說很輕省。
                 
               2. 但是
               1. Message Bean帶著EJB系的榮光,步驟比較繁雜,你需要實現MessageDrivenBean、MessageListener接口,還需要設置EJB的配置信息,然后是deploy....

               2. Spring 1.x 提供的JMS Template簡化了JMS Client端的編程,但并沒有涉及到服務端的改造。

               3. 所以,SpringSide的Message Driven POJO方案

                Spring JMS Template + ActiveMQ + Jencks

          1. 它是Lightweight的,基本上只是普通POJO,不用搞太多東西。

          2. 它是Spring Base的,可以使用Spring的各種特性如IOC、AOP。

          3. 它是Effective的,基于Jencks的JCA Container實現 pool connection,control transactions and manage security。

          4. 但它是withdout EJB Container的。

          其實它還不是100% POJO,除非再用上Lingo,但我已不想走得太遠。

          4.黃金版配置
                如果你想找一個ActiveMQ 3.2 Stable版+Spring的100%可行的配置文件,估計只能到SpringSide項目里看了。網上的文章,不是已過時,就是不切題。

               推薦中英兩份最接近的文檔:
               捷特慈朋(IDEA中國): Spring和Message Bean的整合
               Spring loaded:  Message-Driven POJOs 

               不過它們都有個outdate的地方--ActiveMQ3.2開始不再自帶JCA Cotainer了,而是將其與Gernimo 合作而成了Jencks,需另外安裝。

           5.SpringSide旅游指南

                pom.xml里的JMS部分 --所需的依賴包。
                applicationContext-jms.xml --黃金版配置文件。
                activemq.xml  --AcitveMQ Broker配置文件。
                OrderPlaceMDP.java --Message Driven Pojo。
                JmsTest.java --單元測試用例。
                OrderManger.java的NodifyOrder()函數 --實際應用的地方。 

           POJO太簡單,唯一麻煩的配置文件已注釋,這里也就無話了。

          posted @ 2009-02-11 09:52 Pitey 閱讀(260) | 評論 (0)編輯 收藏

          [導入]一次Java垃圾收集調優實戰

               摘要: GC調優是個很實驗很伽利略的活兒,最后服務的處理速度從1180 tps 上升到1380 tps,調整兩個參數提升17%的性能還是筆很劃算的買賣.....  閱讀全文

          江南白衣 2008-07-09 10:13 發表評論

          文章來源:http://www.aygfsteel.com/calvin/archive/2008/07/09/213535.html

          posted @ 2009-02-11 09:17 Pitey 閱讀(169) | 評論 (0)編輯 收藏

          Spring事物攔截器學習筆記

          Spring事物攔截器,按照通知方式分為[前置通知(Before advice),返回后通知(After returning advice)
          ,拋出后通知(After throwing advice),后通知(After (finally) advice),環繞通知(Around Advice)]
          配置方式分@AspectJ,XML,網上比較多的是Spring1.1或xml+@AspectJ方式配置,例子使用XML方式配置

          1.定義切面類接口,切面類實現這個接口。聲明(如果被代理的目標對象實現了至少一個接口,則會使用JDK動態代理。所有該目標類型實現的接口都將被代理。若該目標對象沒有實現任何接口,則創建一個CGLIB代理)

          public interface ITestAdvice {
           
           
          public void doPlay();
           
           
          public void doStop(Object reval);

          }



          public class Tv implements ITestAdvice{
           
           
           
          public void doStop(Object reval) {
            System.out.println(reval.toString() 
          + "關閉電視機!");
           }

           
           
          public void doPlay() {
            System.out.println(
          "打開電視機!");
           }

           
          }


           

          2.定義前置通知攔截處理類

           

          public class TestMethodBeforeAdvice  {
           
           
          public void before(JoinPoint jpt) {  //參數JoinPoint為默認參數
            System.out.println(
          "正在打開電視..");
           }

           
          }



          3.定義攔截器配置文件

          <bean id="tv" class="com.pitey.demo.Tv" />
          <bean id="beforeAdvice" class="com.pitey.demo.TestMethodBeforeAdvice" />
           
           
          <aop:aspectj-autoproxy proxy-target-class="true"/>
           
          <aop:config>
            
          <!-- 定義切入點 -->
            
          <aop:pointcut id="methodAdvice" expression="execution(* com.pitey.demo.*.*(..))" />
            
          <!-- 定義切面 -->
            
          <aop:aspect id="beforeAdviceAspect" ref="beforeAdvice">
             
          <!-- 定義前置通知 -->   
             
          <aop:before method="before" pointcut-ref="methodAdvice"/>    
           
          </aop:config>


          4.測試一下前置通知

          public static void main(String[] args) {
                  ApplicationContext context 
          = new ClassPathXmlApplicationContext("config\\advice.xml");
                  Tv tv 
          = (Tv)context.getBean("tv");
                  tv.doPlay();        
              }


          結果:
                      正在打開電視機..
                      打開電視機


          5.定義返回后通知攔截處理類

          public class TestAfterReturnAdvice {
           
           
          public void afterReturning(Object retVal) throws Throwable {
            String returnVal 
          = 電視機已經打開!";
            System.out.println(returnVal);
            retVal
          = (Object)returnVal;
           }

           
          }



          6.定義攔截器配置文件

           

          <bean id="afterReturnAdvice" class="com.pitey.demo.TestAfterReturnAdvice"/>
           
          <aop:config>
            
          <!-- 定義切面 -->
            
          <aop:aspect id="afterReturnAdviceAspect" ref="afterReturnAdvice">
             
          <!-- 定義后置返回通知  -->   
             
          <aop:after-returning method="afterReturning" pointcut-ref="methodAdvice" returning="retVal"/> //returing 為返回參數
           </aop:config>


          7.測試一下返回后通知

          public static void main(String[] args) {
                  ApplicationContext context 
          = new ClassPathXmlApplicationContext("config\\advice.xml");
                  Tv tv 
          = (Tv)context.getBean("tv");
                  tv.doPlay();        
              }


          結果:
                      正在打開電視機..
                      打開電視機
                      電視機已經打開
          !


          8.定義環繞通知攔截處理類(環繞通知在一個方法執行之前和之后執行。 它使得通知有機會既在一個方法執行之前又在執行之后運行。并且,它可以決定這個方法在什么時候執行,如何執行,甚至是否執行。 環繞通知經常在在某線程安全的環境下,你需要在一個方法執行之前和之后共享某種狀態的時候使用。 請盡量使用最簡單的滿足你需求的通知。(比如如果前置通知(before advice)也可以適用的情況下不要使用環繞通知))
          通知方法的第一個參數的類型必須是 ProceedingJoinPoint 類型。在通知的主體中,調用 ProceedingJoinPointproceed() 方法來執行真正的方法。 proceed 方法也可能會被調用并且傳入一個 Object[] 對象 - 該數組將作為方法執行時候的參數。

          public class TestMethodIntercepor{
           
           
          public Object doBasicProfiling(ProceedingJoinPoint  pjp) throws Throwable {
            System.out.println(
          "begining");
            Object obj 
          = pjp.proceed();
            
            System.out.println(
          "ending..");
            
          return obj;
           }
           
          }




          9.定義攔截器配置文件

           

          <bean id="aroundAdvice" class="com.pitey.demo.TestMethodIntercepor"/>
           
          <aop:config>
            
          <!-- 定義切面 -->
            
          <aop:aspect id="aroundAspect" ref="aroundAdvice">
           
          <aop:around method="doBasicProfiling" pointcut-ref="methodBeforeAdvice"/>
            
          </aop:aspect>
           
          </aop:config>



          10.測試一下環繞通知

          public static void main(String[] args) {
                  ApplicationContext context 
          = new ClassPathXmlApplicationContext("config\\advice.xml");
                  Tv tv 
          = (Tv)context.getBean("tv");
                  tv.doPlay();        
              }


          結果:
                      begining
                      打開電視機
                      ending..

          posted @ 2009-02-10 23:07 Pitey 閱讀(1689) | 評論 (0)編輯 收藏

          轉:重寫window.setTimeout傳參數(支持傳對象)的方法

          也許你過去在setTimeout中傳參數一直是這樣

          setTimeout("pass(" + argu + ")",1000)

          這樣只能傳字符串,對傳遞object就無能為力了,需要大費文章.然而別忘了,第一個參數還可以是function!!!

          看以下代碼實現向里面的function 傳參數

          <script type="text/javascript">
          var _st = window.setTimeout;window.setTimeout = function(fRef, mDelay) {
          if(typeof fRef == 'function'){ 
            var argu 
          = Array.prototype.slice.call(arguments,2); 
            var f 
          = (function(){ fRef.apply(null, argu); }); 
            return _st(f, mDelay); }
            return
           _st(fRef,mDelay);}

          function test(x){ alert(x);}
          window.setTimeout(test,
          1000,'fason');
          </
          script>

          怎樣?是不是很方便了?代碼其實就很簡單,重載了一下window.setTimeout,用apply去回調前面的function.

          還沒有用過apply,call的可以去查資料,發現版本不夠的看我低版本的實現方法http://blog.csdn.net/fason/archive/2004/07/30/apply_call.aspx

          另外需要知道的是,NS環境下,后面的參數確實是來傳給前面的函數的,IE爛,沒有實現~~~~~~~~~~~~~

          posted @ 2008-03-18 10:21 Pitey 閱讀(3679) | 評論 (1)編輯 收藏

          主站蜘蛛池模板: 肇源县| 海阳市| 广宁县| 仙居县| 康马县| 朝阳县| 德令哈市| 班玛县| 新昌县| 彝良县| 开鲁县| 遂昌县| 东阿县| 墨脱县| 迭部县| 宁陕县| 康马县| 武鸣县| 滨州市| 临安市| 阿拉善右旗| 无棣县| 牙克石市| 昌平区| 天全县| 浦城县| 临城县| 清水县| 桐梓县| 七台河市| 嘉定区| 江北区| 荃湾区| 铜山县| 鹤庆县| 平邑县| 大英县| 宁武县| 茌平县| 东乡县| 平果县|