所谓Dynamic Proxy是这样一种class:
它是在运行时生成的class,在生成它时你必须提供一组interface给它,然后该class就宣称它实现了这些interface。你当然可以把该class的实例当作这些interface中的任何一个来用。当然啦,这个Dynamic Proxy其实就是一个Proxy,它不会替你作实质性的工作,在生成它的实例时你必须提供一个handler,由它接管实际的工作。
package com.laos.javassist;
public interface Service {
public void serviceMethod(String parameter);
}
package com.laos.javassist;
public interface ServiceCallback {
public void doCallback();
}
ServiceConsumer 类实现了Service接口和ServiceCallback接口
package com.laos.javassist;
public class ServiceConsumer implements ServiceCallback,Service {
public void doCallback() {
System.out.println("call back");
}
public void serviceMethod(String parameter) {
System.out.println("service "+parameter);
doCallback();
}
}
package com.laos.javassist;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class InvocationObject implements InvocationHandler {
/**
* 目标对象
*/
private Object obj;
public InvocationObject(Object target){
this.obj = target;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
//目标对象的方法,也即是目标对象实现接口的方法
return method.invoke(obj, args);
}
}
package com.laos.javassist;
import java.lang.reflect.Proxy;
/**
* 动态代理
* @author shuzt
*
*/
public class ProxyFactoryUtils {
/**
* 生成代理对象
* @param interfaceClass
* @param targetClass
* @return
* @throws IllegalArgumentException
* @throws InstantiationException
* @throws IllegalAccessException
*/
public static Object getProxyInstance(Class[] interfaceClasses,Object targetClass)
throws IllegalArgumentException, InstantiationException,
IllegalAccessException {
//调用代理Proxy实例化一个目标对象的实例
return Proxy.newProxyInstance(interfaceClasses[0].getClassLoader(),
interfaceClasses, new InvocationObject(targetClass));
}
public static void main(String[] args){
ServiceConsumer consumer = new ServiceConsumer();
try {
Object proxy = ProxyFactoryUtils.getProxyInstance(new Class[]{Service.class,ServiceCallback.class}, consumer);
Service service = (Service)proxy;
ServiceCallback serviceBack = (ServiceCallback)proxy;
service.serviceMethod("hello");
serviceBack.doCallback();
} catch (IllegalArgumentException e) {
} catch (InstantiationException e) {
} catch (IllegalAccessException e) {
}
}
}
注意:如果ServiceConsumer 没有实现接口,调用不会出现异常!