您的位置:首页 > 编程语言 > Java开发

Java Proxy动态代理

2009-11-11 18:06 573 查看
先看个例子:
接口

package example;

public interface Basic {
public void hello();
}
接口的实现类

package example;

public class BasicService implements Basic {
public void hello() {
Sysytem.out.println("Hello, world");
}
}
实现了InvocationHandler接口的类

package example;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.logging.Level;
import java.util.logging.Logger;

public class LogHandler implements InvocationHandler {
private Logger logger = Logger.getLogger(this.getClass().getName());
private Object delegate;

public Object bind(Object delegate) {
this.delegate = delegate;
return Proxy.newProxyInstance(delegate.getClass().getClassLoader(), delegate.getClass().getInterfaces(), this);
}

@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Object result = null;

try {
log("method starts..." + method);
result = method.invoke(delegate, args);
log("method ends..." + method);
} catch (Exception e) {
log(e.toString());
}
return result;
}

private void log(String message) {
logger.log(Level.INFO, message);
}
}
运行类

package example;

public class ProxyDemo {
public static void main(String[] args) {
LogHandler logHandler = new LogHandler();
Basic helloProxy = (Basic) logHandler.bind(new BasicService());
helloProxy.hello();
}
}
Proxy.newProxyInstance3个参数说明:
1. 根据传入的第二个参数interfaces动态生成一个类$Proxy0,该类
a) 实现interfaces中的接口;
b) 继承了Proxy类;
c) 重写了hashcode,toString,equals等三个方法;
2. 第一个参数classloder将刚生成的$Proxy0类加载到jvm中
3. 第三个参数,调用$Proxy0的构造函数 创建$Proxy0的对象

方法的调用过程:
InvocationHandler,调用一个方法时,不直接调用实现这个方法的真实类,而去调用它的代理,代理通过反射机制找到它的这个方法,然后代理自己去执行,所以invoke()会自动执行。如下例子中方法的调用过程为:

helloProxy.hello()->logHandler.invoke()->basicService.hello()

Proxy动态代理的作用:
Proxy能够在核心业务方法前后做一些辅助工作,如log日志,安全机制等等。Spring中的事务控制就是用动态代理的机制来实现的.使得开发人员可以专住于逻辑的开发(所谓的切面),而其他的工作(如事务的提交和回滚)则交个容器"代"为处理.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: