<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    stone2083

    #

    活用Srping AOP

    總有那么一些代碼,在測試環境下,是不能輕易被調用的。
    比如:
    1)發送系統任務郵件到客戶郵箱,可能一不小心,就把測試郵件發送給了真實客戶的郵箱里;
    2)調用跨公司的系統接口,而對方系統沒有測試環境,每調用一次接口,就會在對方系統產生垃圾數據;
    3)調用的代碼可能需要大量的cpu運算,占用大量的內存空間,消耗大量的資源;
    等等。。。

    為了解決這樣的需求,
    1)在代碼中,到處充斥著這樣的代碼:
    1 if(在測試環境下) {
    2     打印日志;
    3 else {
    4     調用真實的業務邏輯;
    5 }
    于是乎,需要到處維護這樣的代碼,一旦增加此類需求,就需要編寫同樣的代碼

    2)部分懶惰的程序員,連這樣的if...else...也不愿意寫,僅僅在注釋中說明下在測試環境中調用方法的危害性。
    于是,在測試階段,一旦和測試部門溝通不足,導致代碼還是經常被調用到,如果是在作壓力,性能測試,那么危害性可想而已。
    曾發生過,壓力測試某個功能,結果把大量的測試郵件,發送給了客戶,影響很差。


    那么,如何解決這樣的需求場景呢?
    沒錯,采用proxy模式,可以搞定。考慮到現在很多企業都使用Spring作為IOC容器,本文就簡單介紹,如何采用spring aop來解決問題。

    以發送郵件的需求作為虛擬場景。
    現在有個Service,專門負責郵件的發送。
    1. MyService.java
    1 public class MyService {
    2     public void sendMailSafely() {
    3     System.out.println("send mail successfully.");
    4     }
    5 }

    如果這個sendMailSafely被客戶端調用,那么毫無疑問,郵件不管任何環境下,都會被成功發送。
    需要有個方法攔截器,對這個方法做攔截。
    2. MyInterceptor.java
     1 public class MyInterceptor implements MethodInterceptor {
     2 
     3     private boolean isProduction = false;
     4 
     5     @Override
     6     public Object invoke(MethodInvocation invocation) throws Throwable {
     7     if (!isProduction) {
     8         System.out.println("is production environment.do nothing");
     9         return null;
    10     }
    11     return invocation.proceed();
    12     }
    13 
    14     public void setProduction(boolean isProduction) {
    15     this.isProduction = isProduction;
    16     }
    17 
    18 }
    這個攔截器,根據配置文件的參數isProduction判斷是否在正式環境,如果是在測試環境,對方法做攔截,僅僅打印log,不真實調用業務邏輯。

    如何讓sendMailSafely()方法被此攔截器做攔截,所以通過spring配置文件,配置一個advisor,通知對以Safely結尾的方法做攔截
    3.  application.xml
     1 <bean id="safetyAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor" scope="singleton">
     2     <property name="advice">
     3       <ref local="myInterceptor" />
     4     </property>
     5     <property name="patterns">
     6       <list>
     7         <value>.*Safely</value>
     8       </list>
     9     </property>
    10   </bean>

    附上application.xml的全部內容
     1 <beans default-autowire="byName">
     2 
     3   <!-- service實例 -->
     4   <bean id="myService" class="cn.zeroall.javalab.aop.MyService" scope="singleton" />
     5 
     6   <!-- 方法攔截器 -->
     7   <bean id="myInterceptor" class="cn.zeroall.javalab.aop.MyInterceptor" scope="singleton">
     8     <property name="production" value="false" />
     9   </bean>
    10 
    11   <!-- 通知者 -->
    12   <bean id="safetyAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor" scope="singleton">
    13     <property name="advice">
    14       <ref local="myInterceptor" />
    15     </property>
    16     <property name="patterns">
    17       <list>
    18         <value>.*Safely</value>
    19       </list>
    20     </property>
    21   </bean>
    22 
    23   <!-- myService代理類 -->
    24   <bean id="safetyService" class="org.springframework.aop.framework.ProxyFactoryBean" scope="singleton">
    25     <property name="interceptorNames">
    26       <list>
    27         <value>safetyAdvisor</value>
    28       </list>
    29     </property>
    30     <property name="targetName" value="myService" />
    31   </bean>
    32 
    33 </beans>


    寫一個Client類來做演示。
    4. Client.java
     1 public class Client {
     2 
     3     private ApplicationContext ctx = new ClassPathXmlApplicationContext(
     4         "cn/zeroall/javalab/aop/application.xml");;
     5 
     6     public static void main(String[] args) {
     7         Client c = new Client();
     8         c.sendMail();
     9         c.sendMailSafety();
    10     }
    11 
    12     public void sendMail() {
    13         MyService myService = (MyService) ctx.getBean("myService");
    14         myService.sendMailSafely();
    15     }
    16 
    17     public void sendMailSafety() {
    18         MyService myService = (MyService) ctx.getBean("safetyService");
    19         myService.sendMailSafely();
    20     }
    21 
    22 }
    大家可以看看最終輸出的結果內容。

    一直來,我都不會濫用AOP,尤其反感使用AOP來寫業務邏輯內容,但是對于這類非業務邏輯需求,采用spring aop技術那是剛剛好啊。

    最后,附上全部代碼文件(使用maven構建)。
    演示代碼

    posted @ 2008-06-01 15:21 stone2083 閱讀(506) | 評論 (0)編輯 收藏

    由數據訂正想到的

    逐漸地,發覺數據訂正成為了我工作的一部分;
    逐漸地,發覺一天有四個小時的時間在數據訂正上的日子越來越多;
    逐漸地,發覺一天僅僅只有兩個小時投入到編碼的日子也頻繁起來;
    逐漸地,發覺我面向的客戶也不僅僅是PD,測試部門,客服、銷售、銷售支持也成為了我的服務對象。

    我不是做技術支持的,但是客服、銷售、銷售支持的咨詢以及提交數據訂正的申請打擾卻影響到了
    我正常的工作,只能利用晚上加班的時候,去完成一天的編碼工作。
    為什么會有那么多數據訂正發生?

    合理的數據訂正,一般發生于下面的兩種可能:
    1)系統程序存在bug,那么毫無疑問,只能作bug fix工作,然后集中進行一次數據訂正操作;
    2)業務部門,由于不小心,操作失誤等原因,產生錯誤數據。這種情形發生的比較少,一般由這種原因導致的錯誤數據,
    我這邊收到銷售支持提交的數據訂正申請,都會馬上協助完成訂正工作。

    但是,現在越來越多的項目,開發時間嚴重被壓縮,在項目過程中,
    1)業務邏輯本身就考慮不周全,沒有考慮和牽連系統的關系,導致需求邏輯就存在問題;
    2)為了減少開發人日,把本來該交給系統實現的需求,卻考慮人工來完成,增加了人為誤操作的發生概率;
    3)為了減少開發成本,對接口行為不做邏輯驗證處理,而接口錯誤參數,往往增加了系統錯誤數據的產生;
    4)開發時間緊急,開發人員在不熟悉原有系統的基礎上,就進行新功能的開發;過于過程式的開發;
    系統、代碼設計的時間過少;不敢做重夠,等等,導致代碼可讀性很差,維護性不強,易出bug。
    。。。。。。

    由這些原因而造成的bug,形成的錯誤數據,我厭惡為其做數據訂正:
    不在源頭做控制,一旦出了問題,才考慮到手工數據訂正來暫時性的解決問題,這絕對不是一個好的項目團隊的做法。

    我們一直在宣稱要做百年的企業,但是我們目前的系統,又能維持幾年呢?

    posted @ 2008-05-31 21:24 stone2083 閱讀(830) | 評論 (3)編輯 收藏

    最具魅力圣火傳遞城市人氣榜--自動投票機

    最具魅力圣火傳遞城市人氣榜
    在msn網站(http://msn.ynet.com/eventmsnc.jsp?eid=38162866&cd=china)上有最具魔力圣火傳遞城市人氣榜投票。身為紹興人,看到自己的家鄉排名考后,心有不甘,又看到溫州等城市有人采用自動投票工具不斷給自己刷票,于是乎,花費晚上一個小時的時間,用java(選用apache  httpclient組件開發,比較方便。)也寫了一個自動投票小軟件,給紹興投票。
    本想在自己的機器上跑程序,但是考慮到不可能7*24小時運行,于是在網上找到一個jsp免費空間(http://eatj.com),把投票工具部署成web app形式,放到eatj網上,借用人家的服務器,替紹興投票 :)
    通過http://stone2083.s43.eatj.com/web/vote?action=query這個url,可以查看目前所有城市投票總數。

    http://eatj.com,一直來提供了免費空間的服務,作為java初學者,可以拿這個空間練練手,或者作為小作品展示的地方。
    20 MB space;
    提供mysql服務;
    提供tomcat5/tomcat6選擇;
    jdk5/jdk6選擇
    對于免費來說,已經是很好的服務了。
    (但是對于免費空間,每隔6個小時,它會中斷服務,需要手工啟動下,這個有點惡心。)

    posted @ 2008-05-24 23:40 stone2083 閱讀(293) | 評論 (1)編輯 收藏

    第二屆網俠大會隨感

    今天參加了第二屆阿里巴巴網絡俠客行大會
    由于最近加班比較多,早上貪睡不起,錯過了俠客行上午場的會議,據說林斌—谷歌中國工程院副院長在講話中介紹了google的一些技術,沒聽頗為可惜。

    下午場的會議,我選擇是“分會場三 開放服務框架/Open Service framework

    第一場會議是林昊—淘寶網平臺架構師帶來的OSGI分享。
    OSGI確實是一個很好的概念,很好的實現了模塊動態化管理。試想一下,以后軟件的功能可以像硬件一樣,動態化插拔,那是多爽的一件事情。
    Eclipse3版本,就是base on osgi的一個成功案例,用過eclipse開發的同學,一定對eclipse的plugin管理機制很心動,可以動態增加,刪除插件。Eeclipse本身只提供了一個平臺,功能都可以通過插件的方式增加。并且可以按照開發者的需求,增加插件。
    據說jdk7版本,就會在語言級別上支持osgi,這則消息也是振奮人心。----目前jdk只有class(類),package(包)的概念,卻沒有module(模塊)的概念,所謂模塊化開發,僅僅是人工分割package的方式來實現。
    概念是好,但是針對目前以有的功能,如何不傷筋動骨的完成base on osgi或者run on osgi,仍然是一個很大的一個問題。這也是很多企業對osgi僅僅停留在觀望態度上的一個原因。

    第二場會議是黃柳青—普元首席科學家、CTO分享的SCA--感覺他老人家英語說得比中文還好。
    之前,我對SCA沒有任何的了解,甚至連概念都沒有聽過。正好趁此分享機會,對SCA做個概念性的了解。
    SCA(Service Component Architecture)
    這玩意,究其本質,其實是對代碼層面做了可視化組件的封裝。他的概念是,把每個邏輯都看成是一個Component(組件/構件),然后根據不同的業務需要,去配置不同的Component,以及component之間的業務流。
    其實,這個概念是很好的,尤其結合他天生的搭檔OSGI,可以使得所有的開發者眼前一亮。
    試想一下,以后有個系統(Base on OSGI),業務流程中,其中有個業務需求發生了變化,那么只需要開發者開發一個新的component,并且把原先的component動態uninstall,并且把新的component動態install,系統可以在運行期,就完成需求的變動。多爽。
    概念是好,但是是否能流行,還需要時間的考驗。

    第三場會議是 袁紅崗—金蝶中間件首席架構師 介紹 OperaMask,只是自己做這塊內容沒有興趣,就換了會場,去了分會場一 開放平臺/Open Platform

    第三場會議趙進—/阿里軟件首席架構師 介紹 Alisoft SAAS Platform
    這小子年紀輕輕就當上了阿里軟件的首席架構師,只有26歲,對他充滿了敬意。努力向他學習。

    這場分享,感覺只是很膚淺的介紹了阿里軟件saas的平臺。過程中更多的是講了saas的概念和阿里軟件saas的一些模式,沒有涉及到技術細節層面的內容,比較失望。
    SAAS的概念近年來逐漸流行起來。如何構建SAAS平臺系統,是我最關注的點。比如:
    如何發布開放API接口,
    如何管理開放API接口,
    如何對開放API進行測試,
    如何確保開放API接口的安全性,
    API接口采用什么技術調用,SAAS Platform是否統一規范對API的調用,采用什么方式傳輸數據,等等。
    這些細節,都沒有在這次分享中涉及到,太失望了。

    整體來說,這次網絡俠客行,還是讓自己增長了不少見識,學到了不少技術。
    希望阿里巴巴在接下去的幾屆中,能越辦越好,更希望在技術交流會上,能出現更多國內技術的分享,期待國內軟件業的發展 :)

    posted @ 2008-05-24 18:37 stone2083 閱讀(474) | 評論 (0)編輯 收藏

    eclipse下以link方式安裝插件

    eclipse安裝插件的方式,常見的一般有3種:

    1)把插件一股腦兒都扔到$ECLIPSE_HOME/plugins下面;
    這是最方便的一種安裝方式了,但是如果插件一多,就很難管理。如果想停用某幾個插件,嘿嘿,沒轍。。。

    2)利用eclipse的manage configuration功能;
    eclipse-->help-->software updates-->manage configuration
    在這里,添加extension location(外部擴展點),把插件的地址一個一個添加進來。
    這也是我一度使用的方法。可以比較方便的管理插件。
    但是唯一不爽的,就是一旦eclipse重裝,你就需要把這些擴展點一個一個添加進來,比較麻煩。

    3)采用link方式安裝插件
    這是我目前最喜歡的一種安裝eclipse plugins的方式。
    在$ECLIPSE_HOME下,建立一個links目錄。
    links目錄下,創建link文件(文件名和后綴可以隨意指定),比如findbugs.link,內容如下:
    path=/usr/software/eclipse_ext/plugins/findbugs
    path后面跟的就是插件的地址。
    需要注意的是,插件比如采用標準的目錄結構
    eclipse
         |------plugins
         |------features

    采用link的方式,不但方便插件的管理,而且當eclipse重裝的時候,只要把links目錄copy到新的$ECLIPSE_HOME下即可。

    posted @ 2008-04-12 18:13 stone2083 閱讀(918) | 評論 (0)編輯 收藏

    Lightning--thunderbird下的日歷議程工具

    ubuntu下,thunderbird是我首選的郵件管理工具(類似于windows下的outlook)。
    用起來蠻爽,唯一不足就是沒有日歷功能,不能接受來自outlook的事件邀請。

    幸好,thunderbird有個日歷插件,Lightning。剛好滿足我的需求。建議使用。
    放一張截圖上來:

    posted @ 2008-04-04 20:27 stone2083 閱讀(2515) | 評論 (3)編輯 收藏

    firefox優化參數

    firefox是我首選的瀏覽器,但是啟動速度實在不敢恭維。

    從網上找了一些文章,修改了幾個參數。

    前提:地址欄輸入 about:config 進入參數配置頁面

    首選項名稱:config.trim_on_minimize,
    類型:布爾
    鍵值:true 
    作用:最小化時釋放內存
    備注:據說只在windows下有效(怪不得,我在linux下確實感覺沒什么效果)

    首選項名稱:browser.sessionhistory.max_total_viewers
    類型:整數
    鍵值:0  (當然,你也可以設置成你需要緩存的頁面數)
    作用:前進/后退 功能,用于緩存頁面數量

    首選項名稱:network.http.pipelining
    類型:布爾
    鍵值:true
    作用:在http連接中,使用pipelining功能。據說能加速瀏覽速度

    首選項名稱:network.http.pipelining.maxrequests
    類型:整數
    鍵值:8 (據說上限是8)
    作用:是一個實驗性功能,加速瀏覽網站的速度。需要站點的支持。

    首選項名稱:nglayout.initialpaint.delay
    類型:整數
    鍵值:100 (默認值是250)單位是毫秒
    作用:ff收到response后等待n毫秒,進行頁面渲染

    首選項名稱:network.dns.disableIPv6
    類型:布爾
    鍵值:true
    作用:禁用ip6功能(好像跟優化沒什么關系)

    首選項名稱:browser.tabs.loadDivertedInBackground
    類型:布爾
    鍵值:true
    作用:打開新tab時,停留在當前頁面(跟優化沒關系,只是符合我的瀏覽習慣)

    關于這些首選項的意義,具體可以訪問:http://kb.mozillazine.org/network.http.pipelining 得到相應參數的意義。

    最后,做個廣告,效果還是蠻明顯的。推薦使用 :)

    posted @ 2008-03-23 13:57 stone2083 閱讀(700) | 評論 (2)編輯 收藏

    資源如何避免多線程下載

    今天在一次會議中,有朋友問我,如何避免資源被迅雷等工具多線程下載?

    確實,一些中小企業站點,尤其是個人站點,由于沒有過多資金,服務器承受不了大的壓力,站點提供的資源,一旦被迅雷等多線程工具下載,
    對服務器的壓力還是蠻客觀的。

    那么有什么辦法避免多線程下載呢?其實最簡單的辦法,就是服務端根本就不要提供Content-Length值。試想一下,如果多線程下載工具得不到文件總大小值,如何分配去分配每個線程需要下載的量呢?不得已,只能通過單線程下載了。

    以http下載為例,我寫了一個提供下載的servlet,由于不返回Content-Length值(只返回了ContentType值),這個serlvet返回的流,只能單線程下載。
    public class Download extends HttpServlet {

        
    private static final long   serialVersionUID = 8401962046132204450L;

        
    private static final String FILE_PATH        = "/home/jones/tmp/sample.zip";

        @Override
        
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            resp.setContentType(
    "application/octet-stream");

            OutputStream out 
    = resp.getOutputStream();

            FileInputStream in 
    = new FileInputStream(FILE_PATH);
            
    int readLength = 0;
            
    byte[] cache = new byte[1024];
            
    while ((readLength = in.read(cache)) != -1) {
                out.write(cache, 
    0, readLength);
            }
            in.close();

            out.flush();
            out.close();
        }
    }

    同樣的道理,只要配置服務器不要返回Content-Length值,那么就可以有效避免多線程下載了。

    posted @ 2008-03-17 21:58 stone2083 閱讀(886) | 評論 (2)編輯 收藏

    CGlib簡單介紹

         摘要: CGlib概述: cglib(Code Generation Library)是一個強大的,高性能,高質量的Code生成類庫。它可以在運行期擴展Java類與實現Java接口。 cglib封裝了asm,可以在運行期動態生成新的class。 cglib用于AOP,jdk中的proxy必須基于接口,cglib卻沒有這個限制。 CGlib應用: 以一個實例在簡單介紹下cglib的應用。 我...  閱讀全文

    posted @ 2008-03-16 22:50 stone2083 閱讀(35629) | 評論 (22)編輯 收藏

    jdk gc簡介

    常用的GC算法:
    1)標記非活動對象
    --何為非活動對象,通俗的講,就是無引用的對象。
    • 追蹤root對象算法: 深度追蹤root對象,將heap中所有被引用到的root做標志,所有未被標志的對象視為非活動對象,所占用的空間視為非活動內存。
    2)清理非活動對象
    • Copy算法:          
    • 方法:將內存分為兩個區域(from space和to space)。所有的對象分配內存都分配到from space。在清理非活動對象階段,把所有標志為活動的對象,copy到to space,之后清楚from space空間。然后互換from sapce和to space的身份。既原先的from space變成to sapce,原先的to space變成from space。每次清理,重復上述過程。
    • 優點:copy算法不理會非活動對象,copy數量僅僅取決為活動對象的數量。并且在copy的同時,整理了heap空間,即,to space的空間使用始終是連續的,內存使用效率得到提高。
    • 缺點:劃分from space和to space,內存的使用率是1/2。
    •   Compaction算法
      • 方法:在清理非活動對象階段,刪除非活動對象占用內存,并且把活動對象向heap的底部移動,直到所有的活動對象被移到heap的一側。
      • 優點:無須劃分from sapce和to space,提高內存的使用率。并且compaction后的內存空間也是連續分配的。
      • 缺點:該算法相對比較復雜。
    sun jdk gc介紹:
    在減少gc之前,先來看看來自IBM的一組統計數據:
    98%的java對象,在創建之后不久就變成了非活動對象;只有2%的對象,會在長時間一直處于活動狀態。

    如果能對這兩種對象區分對象,那么會提交GC的效率。在sun jdk gc中(具體的說,是在jdk1.4之后的版本),提出了不同生命周期的GC策略。
    • young generation
      • 生命周期很短的對象,歸為young generation。由于生命周期很短,這部分對象在gc的時候,很大部分的對象已經成為非活動對象。因此針對young  generation的對象,采用copy算法,只需要將少量的存活下來的對象copy到to space。存活的對象數量越少,那么copy算法的效率越高。
      • young generation的gc稱為minor gc。經過數次minor gc,依舊存活的對象,將被移出young generation,移到tenured generation(下面將會介紹)

      • young generation分為:
        • eden:每當對象創建的時候,總是被分配在這個區域
        • survivor1:copy算法中的from space
        • survivor2:copy算法中的to sapce (備注:其中survivor1和survivor2的身份在每次minor gc后被互換)
      • minor gc的時候,會把eden+survivor1(2)的對象copy到survivor2(1)去。
    • tenured generation
      • 生命周期較常的對象,歸入到tenured generation。一般是經過多次minor gc,還 依舊存活的對象,將移入到tenured generation。(當然,在minor gc中如果存活的對象的超過survivor的容量,放不下的對象會直接移入到tenured generation)
      • tenured generation的gc稱為major gc,就是通常說的full gc。
      • 采用compactiion算法。由于tenured generaion區域比較大,而且通常對象生命周期都比較常,compaction需要一定時間。所以這部分的gc時間比較長。
      • minor gc可能引發full gc。當eden+from space的空間大于tenured generation區的剩余空間時,會引發full gc。這是悲觀算法,要確保eden+from space的對象如果都存活,必須有足夠的tenured generation空間存放這些對象。
    • Permanet Generation:
      • 該區域比較穩定,主要用于存放classloader信息,比如類信息和method信息。
      • 對于spring hibernate這些需要動態類型支持的框架,這個區域需要足夠的空間。

    這部分內容相對比較理論,可以結合jstat,jmap等命令(當然也可以使用jconsole,jprofile,gciewer等工具),觀察jdk gc的情況。

    posted @ 2008-03-15 17:11 stone2083 閱讀(2020) | 評論 (2)編輯 收藏

    僅列出標題
    共10頁: First 上一頁 2 3 4 5 6 7 8 9 10 下一頁 
    主站蜘蛛池模板: 亚洲激情电影在线| 久久人午夜亚洲精品无码区| 免费无码又黄又爽又刺激| 亚洲精品久久无码| 亚洲视频在线一区二区| 99久久人妻精品免费一区| 亚洲乱亚洲乱妇24p| 成人午夜亚洲精品无码网站| 91九色视频无限观看免费| 看全免费的一级毛片| 亚洲AV福利天堂一区二区三| 午夜视频免费观看| 免费看少妇高潮成人片| 亚洲中文字幕久久精品蜜桃| 亚洲日本一区二区三区在线| 成人免费无码大片a毛片| 日本高清不卡aⅴ免费网站| 亚洲性线免费观看视频成熟| 国产亚洲精品成人AA片新蒲金 | 国产成人亚洲午夜电影| 亚洲小视频在线观看| 免费v片视频在线观看视频| 久久精品免费一区二区| www在线观看播放免费视频日本| 激情综合亚洲色婷婷五月APP| 亚洲午夜福利AV一区二区无码| 免费a级毛片高清视频不卡| 一个人免费视频在线观看www| 在线观看亚洲专区| 亚洲毛片无码专区亚洲乱| 中文亚洲AV片不卡在线观看 | 亚洲第一永久AV网站久久精品男人的天堂AV | 国产亚洲精午夜久久久久久| 亚洲天堂免费在线| 黄色网址在线免费| 一级人做人a爰免费视频| 亚洲av无码一区二区三区天堂| 精品日韩亚洲AV无码| 永久亚洲成a人片777777| 免费一级毛片不卡在线播放| 毛片免费观看的视频在线|