首页 > 代码库 > 利用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");