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