利用java的代理建立緩存

xb68 9年前發布 | 19K 次閱讀 Java開發 Java

背景:

         為了實現組件的復用,幾乎所有的項目都會調用一個通用的用戶組件(org)。各系統和org之間是使用webservice技術進行通,主要是org提供了webservice業務接口。經過了一段時間的使用發現組件相當穩定,正常情況下幾乎可以滿足所有系統的要求。只是有一個問題比較突出就是當一個方法包含過多的webservice請求時還是會有性能問題,這個問題應該說是webservice的通病。所以這里提供一種解決方法,建立緩存機制。

分析:

       首先建立緩存位置其實有兩個選擇,一是建立在org服務器端,二是建立在客戶端。建立在org服務的話可以優化數據庫查詢的時間,建立在客戶端的話可節省調用的時間+數據庫查詢的時間,所以效率上肯定更高,但是需要付出的代價是需要在每個調用系統中修改相應的代碼。
       其次建立緩存方式也有所不同,最簡單的方式是直接添加一個支持緩存方法,譬如 findCacheUserByDeptId,但是這種方法的缺點也是需要修改過多的代碼,所以這里我使用的是通過代理方式實現緩存。優點是只需要修改client的聲明方式,無需修改具體調用的代碼。

實現步驟:


1  建立一個代理類
       新建 IOrgServiceCachePxy 繼承InvocationHandler接口

2 實現接口的invoke(Object proxy, Method method, Object[] args)  方法
       當被代理class對象的任何業務方法被調用時,這個方法就會被觸發。而且這個方法獲取這個業務方法的方法信息、參數信息,所以可以輕松實現對這個方法前置、后置操作。相關的緩存操作可以是在改方法中實現的,如果緩存方法比較多的話建議添加多個緩存實現方法,然后根據方法名稱分別調用。

3 建立代理對象和實體對象的關聯
        使用java.lang.reflect.Proxy.newProxyInstance 方法

代理對象的完整代碼
    package com.megait.orgv2.webservice.cache;  

    import java.lang.reflect.InvocationHandler;  
    import java.lang.reflect.InvocationTargetException;  
    import java.lang.reflect.Method;  
    import java.lang.reflect.Proxy;  

    import com.megait.orgv2.webservice.client.model.ArrayOfDepartment;  
    import com.megait.orgv2.webservice.client.model.ArrayOfUser;  
    import com.megait.orgv2.webservice.client.model.Department;  
    import com.megait.orgv2.webservice.client.model.User;  

    public class IOrgServiceCachePxy implements InvocationHandler {    
        private Object target;    
        /** 
         * 獲取代理對象,必須是個實例(在這個對象的基礎進行添加其它行為) 
         * @param target 
         * @return 
         */  
        public Object getProxyInstance(Object target){    
            this.target = target;    
            return Proxy.newProxyInstance(target.getClass().getClassLoader(),     
                    target.getClass().getInterfaces(), this);    
        }    
        /** 
         * target 實例,被調用時會觸發此方法 
         * InvocationHandler接口的方法  
         */  
        public Object invoke(Object proxy, Method method, Object[] args)    
                throws Throwable {    
            Object result = null;  
            //System.out.println(Thread.currentThread().getName() +": 進入IOrgServiceCachePxy。。。");  
            if(method.getName().equals("findAllDepartment")){  
                //System.out.println("args[0]:"+args[0]+",args:[1]"+args[1]+",args[2]:"+args[2]);  
                result = findAllDepartment(method, args);  
            }else if(method.getName().equals("findDeptByActDeptId")){  
                // System.out.println("args[0]:"+args[0]+",args[1]:"+args[1]);  
                result = findDeptByActDeptId(method, args);  
            }else if(method.getName().equals("findUserByUserId")){  
                result = findUserByUserId(method, args);  
            }else if(method.getName().equals("findUserByDeptId")){  
                result = findUserByDeptId(method, args);  
            }else{ //非過濾條件  
                result = method.invoke(target, args);  
            }  
            // System.out.println(Thread.currentThread().getName() +": 22222222222222222");  
            // System.out.println("after target method...");    
            return result;    
        }  

        // 獲得所有的部門  
        private Object findAllDepartment(Method method, Object[] args)  
                throws IllegalAccessException, InvocationTargetException {  
            Object result;  
            // 只有符合參數要求的方法才會進行緩存處理(只對獲取當前有效部門列表)  
            if(args[0].equals("0") && args[1].equals("y") && args[2].equals(0)){  
                // System.out.println(Thread.currentThread().getName() +": 進入IOrgServiceCachePxy。。。2");  
                //System.out.println("方法可進行緩存");  
                String key = "findAllDepartment_0_y_0";  
                if(OrgCachePools.allDeptPools.containsKey(key)){  
                    //System.out.println("從緩存中獲取"+key);  
                    return OrgCachePools.allDeptPools.get(key);  
                }  
                result = method.invoke(target, args);  
                final ArrayOfDepartment arrayDept = (ArrayOfDepartment)result;  
                OrgCachePools.allDeptPools.put(key, arrayDept);  
            }else{  
                //System.out.println(Thread.currentThread().getName() +": 進入IOrgServiceCachePxy。。。3");  
                //System.out.println("不符合緩存條件");  
                result = method.invoke(target, args);  
            }  
            return result;  
        }  

        // 獲得部門對象 根據實體id  
        private Object findDeptByActDeptId(Method method, Object[] args)  
                throws IllegalAccessException, InvocationTargetException {  
            Object result;  
            // 只有符合參數要求的方法才會進行緩存處理(只對獲取當前有效部門列表)  
            if(args[1].equals(0) ){  
                // System.out.println(Thread.currentThread().getName() +": 進入IOrgServiceCachePxy。。。2");  
                //System.out.println("方法可進行緩存");  
                String key = args[0]+"_0";  
                if(OrgCachePools.deptPools.containsKey(key)){  
                    // System.out.println("從緩存中獲取"+key);  
                    return OrgCachePools.deptPools.get(key);  
                }  
                result = method.invoke(target, args);  
                if(result!=null){  
                    Department dept = (Department)result;  
                    OrgCachePools.deptPools.put(key, dept);  
                }  
            }else{  
                //System.out.println(Thread.currentThread().getName() +": 進入IOrgServiceCachePxy。。。3");  
                // System.out.println("方法參數不符");  
                result = method.invoke(target, args);  
            }  
            return result;  
        }  

        // 獲得用戶對象  
        private Object findUserByUserId(Method method, Object[] args)  
                throws IllegalAccessException, InvocationTargetException {  
            Object result;  
            // 只有符合參數要求的方法才會進行緩存處理(只對獲取當前有效部門列表)  
            if(args[1].equals(0) ){  
                // System.out.println(Thread.currentThread().getName() +": 進入IOrgServiceCachePxy。。。2");  
                //System.out.println("方法可進行緩存");  
                String key = args[0]+"_0";  
                if(OrgCachePools.userPools.containsKey(key)){  
                    // System.out.println("從緩存中獲取"+key);  
                    return OrgCachePools.userPools.get(key);  
                }  
                result = method.invoke(target, args);  
                User dept = (User)result;  
                OrgCachePools.userPools.put(key, dept);  
            }else{  
                //System.out.println(Thread.currentThread().getName() +": 進入IOrgServiceCachePxy。。。3");  
                // System.out.println("方法參數不符");  
                result = method.invoke(target, args);  
            }  
            return result;  
        }  

        // 獲得用戶對象  
        private Object findUserByDeptId(Method method, Object[] args)  
                throws IllegalAccessException, InvocationTargetException {  
            Object result;  
            // 只有符合參數要求的方法才會進行緩存處理(只對獲取當前有效部門列表)  
            if(args[1].equals("y") ){  
                // System.out.println(Thread.currentThread().getName() +": 進入IOrgServiceCachePxy。。。2");  
                //System.out.println("方法可進行緩存");  
                String key = args[0]+"_y";  
                if(OrgCachePools.deptUserPools.containsKey(key)){  
                    // System.out.println("從緩存中獲取"+key);  
                    return OrgCachePools.deptUserPools.get(key);  
                }  
                result = method.invoke(target, args);  
                ArrayOfUser userList = (ArrayOfUser)result;  
                OrgCachePools.deptUserPools.put(key, userList);  
            }else{  
                //System.out.println(Thread.currentThread().getName() +": 進入IOrgServiceCachePxy。。。3");  
                // System.out.println("方法參數不符");  
                result = method.invoke(target, args);  
            }  
            return result;  
        }    




    }    

調用代碼的差別

    // 原來的代碼  
    IOrgServiceClient client = new IOrgServiceClient();  
    IOrgServicePortType service = client.getIOrgServiceHttpPort();  

    ArrayOfUser userArr = service.findUserByDeptId(bgsVerid, "y");  


    // 緩存代碼  
    IOrgServiceClient client = new IOrgServiceClient();  
    IOrgServiceCachePxy proxy = new IOrgServiceCachePxy();    
    cacheService = (IOrgServicePortType)proxy.getProxyInstance(client.getIOrgServiceHttpPort());  

    ArrayOfUser userArr = service.findUserByDeptId(bgsVerid, "y");  

 本文由用戶 xb68 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!