动态代理

代理的作用:为了安全,远程调用,屏蔽客户端直接访问真实对象等,如:dubbo中的远程调用就使用 了代理。
以下为具体实现:
1.接口:

package proxy;

import java.util.List;

public interface Query {
	List<String> queryList();
	String getName();
}

2.实现类:

package proxy;

import java.util.List;

public class QueryImpl implements Query{

	@Override
	public List<String> queryList() {
		return null;
	}

	
	 /**
	  * @Title: getName
	  * @Description: TODO(这里用一句话描述这个方法的作用)
	  * @param @return    参数
	  * @author shidebin
	  * @date 2018年10月9日
	  * @throws
	  */
	    
	@Override
	public String getName() {
		return "ss";
	}

}

2.静态代理:

package proxy;

import java.util.List;

public class StaticProxy implements Query{
	private QueryImpl query= null;

	@Override
	public List<String> queryList() {
		if(query == null) {
			query = new QueryImpl();
		}
		return query.queryList();
	}

	
	 /**
	  * @Title: getName
	  * @Description: TODO(这里用一句话描述这个方法的作用)
	  * @param @return    参数
	  * @author shidebin
	  * @date 2018年10月9日
	  * @throws
	  */
	@Override
	public String getName() {
		if(query == null) {
			query = new QueryImpl();
		}
		return query.getName();
	}
	
}

缺点:有几个方法要写几个实现,比较麻烦。
3.用java JDK API实现动态代理:

package proxy;

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

public class JDKProxy implements InvocationHandler{
	private QueryImpl query;
	public JDKProxy(QueryImpl query) {
		this.query = query;
	}
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		
		return method.invoke(query, args);
	}
	public static Query createQueryProxy() {
		return (Query)Proxy.newProxyInstance(ClassLoader.getSystemClassLoader()
		, new Class[] {Query.class}, new JDKProxy(new QueryImpl()));
	}
}

4.用cglib实现动态代理:

package proxy;

import java.lang.reflect.Method;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

public class CglibProxy implements MethodInterceptor{
	private QueryImpl query = null;
	@Override
	public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable {
		if(query == null) {
			query = new QueryImpl();
		}
		return arg1.invoke(query, arg2);
	}
	public static Query createQuery() {
		Enhancer hancer= new Enhancer();
		hancer.setCallback(new CglibProxy());
		hancer.setInterfaces(new Class[] {Query.class});
		return (Query)hancer.create();
	}
}

5.俩种动态代理的性能比较:

package proxy;

public class ProxyTest {
	public static void main(String[] args) {
		int circle = 30000000;
		long begin = System.currentTimeMillis();
		Query jdk = JDKProxy.createQueryProxy();
		System.out.println("jdk create:"+(System.currentTimeMillis() - begin));
		begin = System.currentTimeMillis();
		for(int i = 0;i<circle;i++) {
			jdk.queryList();
		}
		System.out.println("jdk query:"+(System.currentTimeMillis() - begin));
		begin = System.currentTimeMillis();
		for(int i = 0;i<circle;i++) {
			jdk.getName();
		}
		System.out.println("jdk getName:"+(System.currentTimeMillis() - begin));
		Query lib = CglibProxy.createQuery();
		System.out.println("lib create:"+(System.currentTimeMillis() - begin));
		begin = System.currentTimeMillis();
		for(int i = 0;i<circle;i++) {
			lib.queryList();
		}
		System.out.println("lib query:"+(System.currentTimeMillis() - begin));
		begin = System.currentTimeMillis();
		for(int i = 0;i<circle;i++) {
			lib.getName();
		}
		System.out.println("lib getName:"+(System.currentTimeMillis() - begin));
	}
}

输出:

jdk create:4
jdk query:63
jdk getName:130
lib create:228
lib query:137
lib getName:144

运行环境是jdk1.8,可以看出jdk自带的动态代理效率要高

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值