静态代理
import java.util.logging.Level;
import java.util.logging.Logger;
//定义接口,代理类和被代理类都要实现这个接口
interface IHello {
public void hello (String name) ;
}
//被代理类
class HelloSpeaker implements IHello {
public void hello(String name) {
System.out.println("hello:"+name);
}
}
//代理类
class HelloProxy implements IHello {
private Logger logger = Logger.getLogger(this.getClass().getName());
private IHello helloObject;
public HelloProxy(IHello helloObject) {
this.helloObject = helloObject;
}
@Override
public void hello(String name ){
log("hello method starts...");
helloObject.hello(name);
log("hello method ends...");
}
private void log(String msg) {
logger.log(Level.INFO,msg);
}
}
//测试类
public class ProxyTest {
public static void main(String[] args) {
IHello proxy = new HelloProxy(new HelloSpeaker());
proxy.hello("Ericiverson");
}
}
对于运行结果需要提醒的是,代理对象的业务逻辑(这里就是打印出Hello,Justin)和
日志等事物的执行是由两个线程执行的,所以结果也可能是日志信息先出现,再打印字符。
简单总结一下,静态代理要求代理对象和被代理对象都实现同一个接口。执行的时候执
行的是代理对象,但代理对象调用了被代理对象,这样业务逻辑实际上是由被代理对象提供
的,代理对象只是作为一个载体而已。
静态代理的缺陷就在于必须实现同一个接口,在程序规模稍大时就无法胜任。这里通过这个
例子来了解代理工作的基本原理。
动态代理:
从JDK1.3 开始,Java提供了可以开发动态代理的API。动态代理和静态代理的区别,
就是动态代理中的代理类是由java.lang.reflect.Proxy类在运行期时根据接口定义,采用Java
反射功能动态生成的。
Java动态代理类位于Java.lang.reflect包下,一般主要涉及到以下两个类:
(1). Interface InvocationHandler:该接口中仅定义了一个方法Object:invoke(Object obj,Method
method, Object[] args)。
(2).Proxy:该类即为动态代理类,其中主要包含以下内容:
l Protected Proxy(InvocationHandler h)
l Static Class getProxyClass (ClassLoader loader, Class[] interfaces)
l Static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)
所谓Dynamic Proxy是这样一种class:它是在运行时生成的class,在生成它时你必须
提供一组interface给它,然后该class 就宣称它实现了这些interface。你当然可以把该class
的实例当作这些interface 中的任何一个来用。当然啦,这个Dynamic Proxy其实就是一个
Proxy,它不会替你作实质性的工作,在生成它的实例时你必须提供一个handler,由它接管
实际的工作。
我们采取研究代码的方式来理解动态代理API的内容。
下面的代码定义了一个LogHandler类,它是一个代理类,提供日志的有关功能。这个
类是个动态代理类,对应动态代理类要求必须实现InvocationHandler接口,并overriding该
接口中定义的invoke()方法。
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;
//动态代理 动态代理必须实现InvocationHandler接口
interface IHello {
public void hello (String name) ;
public void sayHello(String name);
}
//被代理类
class HelloSpeaker implements IHello {
public void hello(String name) {
System.out.println("hello:"+name);
}
@Override
public void sayHello(String name) {
System.out.println("SayHello:"+name);
}
}
//代理类
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(),new Class[]{IHello.class},this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Object result = null;
log("method starts oyp..."+method);
result = method.invoke(delegate, args);
logger.log(Level.INFO,"method ends oyp..."+method);
return null;
}
private void log(String message) {
logger.log(Level.INFO,message);
}
}
//测试类
public class ProxyTestTwo {
public static void main(String[] args) {
LogHandler logHandler = new LogHandler();
IHello helloProxy = (IHello)logHandler.bind(new HelloSpeaker());
helloProxy.hello("1231");
helloProxy.sayHello("sdfasf");
}
}
http://hi.baidu.com/ou_yang_/blog/item/f44edd13feac6d2bdf540164.html