java动态代理之一:java Proxy实现

动态代理类是一个实现在创建类时在运行时指定的接口列表的类。


InvocationHandler handler = new MyInvocationHandler(...);
Class proxyClass = Proxy.getProxyClass(
Foo.class.getClassLoader(), new Class[] { Foo.class });
Foo f = (Foo) proxyClass.
getConstructor(new Class[] { InvocationHandler.class }).
newInstance(new Object[] { handler });

proxyClass 是一份动态生成的字节码,在创建时需指定一个加载器 Foo.class.getClassLoader()(在此可理解为:给他指定一个妈妈),给它一个接口对象数组,即该代理类实现了哪些接口。
调用 Class proxyClass = Proxy.getProxyClass(
Foo.class.getClassLoader(), new Class[] { Foo.class });
即生成了一个动态字节码。通过反射查看它的构造函数,发现它的构造函数需要传递一个InvocationHandler 对象。 其实在生成的动态字节码实现接口的方法中,都是调用了InvocationHandler 对象的invoke方法。
在这里我们可以大概想象生成的动态字节码的内部结构:

public classs Xxx$Proxy{
private InvocationHandler invocationHandler ;
public Xxx$Proxy(InvocationHandler invocationHandler ){
this.invocationHandler =invocationHandler ;
}
Method1(Object[] args){
invocationHandler.invoke(this,...);
}
Method2(Object[] args){
invocationHandler.invoke(this,...);
}

}


[quote][/quote]我们在看InvocationHandler 接口,其内部就一个方法
Object invoke(Object proxy,
Method method,
Object[] args)
throws Throwable

需要一个代理对象,方法对象,方法参数。

通常我们在InvocationHandler实现类中,放入真实的角色和Advice(增强功能类)。
在通过反射执行method对象的Invoke方法时,传入真实对象。

上面代理实现是通过分部执行,Proxy类的newProxyInstance(Foo.class.getClassLoader(),
new Class[] { Foo.class },
handler);

方法可以一次生成该代理对象,由以上的解释,我们不难想象需要三个参数。即给它个妈妈(加载器),实现了那些接口(接口数组),InvocationHandler对象。

下面是一个动态代理工厂:



public class ProxyFactoryBean {

private Advice advice;
private Object target;

public Advice getAdvice() {
return advice;
}

public void setAdvice(Advice advice) {
this.advice = advice;
}

public Object getTarget() {
return target;
}

public void setTarget(Object target) {
this.target = target;
}

public Object getProxy() {
Object proxy = Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new InvocationHandler(){
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
advice.beforeMethod(method);
Object retVal = method.invoke(target, args);
advice.afterMethod(method);
return retVal;

}
}
);
return proxy;
}



我们可以动态的指定一个代理目标target,和增强功能对象advice。使用getProxy即会生成一个动态代理对象。

该种代理方式,代理的对象必须是实现了某个接口。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值