代理模式

参考:《java程序性能优化》--葛一鸣

代理模式,屏蔽用户对真实对象的访问,而用代理对象完成用户请求。

好处:

(1)安全,屏蔽客户端之间访问真实对象。

(2)增加真实对象功能,比如spring的拦截器,利用代理模式,实现方法前和方法后等拦截。、

(3)延迟加载

角色:

主题接口、真实主题、代理类、客户端主类

1、普通代理模式

public interface IQuery{
    public String request();
}
public class Query implements IQuery{
    public Query(){
        ...
    }
    public String request(){
        return "request";
    }
}
public class QueryProxy implements IQuery{
    private Query query=null;
    public String request(){
       if(query!=null)
           real=new Query():
       return real;
   }
}
public Class Client{
    public static void main(String[] args){         
        IQuery query=new QueryProxy();
        query.request();
   }
}

2、动态代理

动态代理是指在运行时,动态生成代理类。即,代理类的字节码将在运行时生成并载入当前的ClassLoader。

好处:

(1)不需要为真实主题写一个形式上完全一样的封装类,当主题接口中方法很多时,不用为每一个接口写一个代理方法,可以节省大量代码。

(2)提升系统灵活性,例如有些动态代理的生成方法可以在运行时指定代理类的执行逻辑。

a、JDK自带的动态代理

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

public class JdkDbQueryHandler implements InvocationHandler {
	IDBQuery real = null;
	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		if(real==null)
			real=new DBQuery();
		return real;
	}
}
public static IDBQuery createJdkProxy(){
	IDBQuery jdkProxy = (IDBQuery) Proxy.newProxyInstance(
			ClassLoader.getSystemClassLoader(), new Class[]{IDBQuery.class}, 
			new JdkDbQueryHandler());
	return jdkProxy;
}
b、CGLIB

public class CglibDbQueryInterceptor implements MethodInterceptor{
	IDBQuery real =null;
	public Object intercept() throws Throwable{
		if(real==null)
			real=new DBQuery();
		return real.request();
	}
}
public static IDBQuery createCglibProxy(){
	Enhancer enhancer=new Enhancer();
	enhancer.setCallback(new CglibDbQueryInterceptor());	//指定切入点,定义代理类逻辑
	enhancer.setInterface(new Class[]{IDBQuery.class});	//指定实现的接口
	IDBQuery cglibProxy=(IDBQuery)enhancer.create();	//生成代理类的实例
	return cglibProxy;
}
c、javassit

public class JavassistDynDbQueryHandler implements MethodHandler{
	IDBQuery real=null;
	public Object invoke(Object arg0,Method arg1,Method arg2,Object[] arg3) 
		throws Throwable{
		if(real==null)
			real=new DBQuery();
		return real.request();
	}
}

public static IDBQuery createJavassistDynProxy() throws Exception{
	ProxyFactory proxyFactory = new ProxyFactory();
	proxyFactory.setInterfaces(new Class[]{IDBQuery.class});
	Class proxyClass=proxyFactory.createClass();
	IDBQuery javassistProxy = (IDBQuery) proxyClass.newInstance();
	((ProxyObject)javassistProxy).setHandler(new JavassistDynDbQueryHandler());
	return javassistProxy;
}








  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值