Java代理(JDK动态代理)

对于静态代理,如果接口发生改变,那么代理类和原始对象都要发生改变。而且每一个原始对象都需要一个代理类完成代理操作。因此类数目会相当多。

因此使用jdk动态代理时,动态代理类始终只有一个invoke方法,当接口发生改变时,动态代理的接口不用随之改变。但是要求目标对象必须实现接口,因为它创建代理对象的时候是根据接口创建的。如果不实现接口,jdk无法给目标对象创建代理对象。

动态代理现在只能代理接口,实现是依靠Java反射机制和动态生成class技术。而Spring的AOP也就是应用到jdk动态代理技术。

实例如下:依旧使用保护代理模拟权限控制

1、接口:

/**
 * 由于使用jdk动态代理,必须依赖于实现接口
 * @author cai.wuxin
 *
 */
public interface OAOperate {

	
	public void add();
	
	public void select();
	
	public void delete();
}

2、目标对象:

public class OAOperateImpl implements OAOperate{

	private String name;
	
	private int flag;
	
	public OAOperateImpl(String name,int flag) {
		this.name = name;
		this.flag = flag;
	}
	
	public int getFlag(){
		return this.flag;
	}
	
	@Override
	public void add() {
		//省略相应操作
	}

	@Override
	public void select() {
		//省略相应操作
	}

	/**
	 * delete需要权限设置
	 */
	@Override
	public void delete() {
		//省略相应操作
		System.out.println("删除操作");
	}

}


3、代理对象:

public class DynamicProxy implements InvocationHandler{

	private OAOperateImpl operate = null;
	
	public OAOperate getProxyInterface(OAOperateImpl operate){
		this.operate = operate;
		OAOperate oApi = (OAOperate)Proxy.newProxyInstance(
				operate.getClass().getClassLoader(), 
				operate.getClass().getInterfaces(), 
				this);
		return oApi;
	}
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		// TODO Auto-generated method stub
		if(method.getName().startsWith("delete")){
			if(operate.getFlag()==4){
				return method.invoke(operate, args);
			}else{
				System.out.println("权限不足");
			}
		}else{
			return method.invoke(operate, args);
		}
		return null;
	}

}

4、客户端实现:

public class Client {

	public static void main(String []args){
		OAOperateImpl o1 = new OAOperateImpl("lilei",3);
		OAOperateImpl o2 = new OAOperateImpl("hanmeimei",4);
		
		DynamicProxy dp1 = new DynamicProxy();
		DynamicProxy dp2 = new DynamicProxy();
		
		OAOperate proxy1 = dp1.getProxyInterface(o1);
		OAOperate proxy2 = dp2.getProxyInterface(o2);
		
		proxy1.delete();
		proxy2.delete();
	}
}

5、运行结果:

权限不足
删除操作


以上很轻易就实现对原始对象的权限控制。在代理类中无需实现每个接口的方法,只需要invoke方法即可。而这种实现也可以看出Spring AOP的实现雏形。完成前后增强。

但是限制还是在于获得代理类必须依赖于接口。


更加深入的分析有关如何生成代理对象,代理对象如何代用invoke方法,本人还未深究。如果有感兴趣者可以查看源码或者参考以下文章:

http://rejoy.iteye.com/blog/1627405


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值