1、简介
在java常用的设计模式中有一种模式叫:代理模式----通过一个代理类负责处理被代理类(委托类)的调用,如果你了解或使用过Spring的切面(AOP),可以更好的理解何为代理,通俗的讲就是在一个类的方法执行的前后加入操作(如进入和完成方法打印日志),实际上Spring正是使用java的动态代理来实现切面的;一般代理类和委托类实现同样的接口,代理类通过调用委托类对象的方法真正的实现服务,并且可以在实现的前后增加需要的处理。
/**
* 手机生产接口
* @author hwz
*
*/
public interface PhoneBuilder {
public void buildAPhone();
}
/**
* 手机生产厂商
* @author hwz
*
*/
public class PhoneVendor implements PhoneBuilder{
@Override
public void buildAPhone() {
//设计和生产手机
System.out.println("design and build a phone");
}
}
/**
* 代理工厂类
* @author hwz
*
*/
public class PhoneBuilderProxyFactory implements PhoneBuilder {
private PhoneBuilder phoneBuilder;//代理类一把通过聚合持有委托类的一个实例
public PhoneBuilderProxyFactory(PhoneBuilder phoneBuilder) {
this.phoneBuilder = phoneBuilder;
}
@Override
public void buildAPhone() {
phoneBuilder.buildAPhone();
//组装手机
System.out.println("phone assemble and produce...");
}
}
/**
* 静态代理测试
* @author hwz
*
*/
public class StaticProxyTest {
public static void main(String[] args) {
PhoneVendor realBuilder = new PhoneVendor();
PhoneBuilderProxyFactory proxyBuilder = new PhoneBuilderProxyFactory(realBuilder);
proxyBuilder.buildAPhone();
}
}
/**
* 一个简单的外部接口
* @author hwz
*/
public interface OneOuterInterface {
/**
* 方法一:翻转字符串
* @param str
* @return
*/
public String methodOne(String str);
/**
* 方法二:计算两个数的乘积
* @param a
* @param b
* @return
*/
public int methodSecond(int a, int b);
}
/**
* 简单的外部类
* @author hwz
*
*/
public class OneOuterClass implements OneOuterInterface {
@Override
public String methodOne(String str) {
return new StringBuilder(str).reverse().toString();
}
@Override
public int methodSecond(int a, int b) {
return a*b;
}
}
/**
* 代理类
* @author hwz
*
*/
public class InnerProxyClass implements OneOuterInterface {
private OneOuterInterface outer;
public InnerProxyClass(OneOuterInterface outer) {
this.outer = outer;
}
@Override
public String methodOne(String str) {
System.out.println("Enter methodOne,str=" + str);
String result = outer.methodOne(str);
System.out.println("Leave methodOne,result=" + result);
return result;
}
@Override
public int methodSecond(int a, int b) {
System.out.println("Enter methodSecond,a=" + a + ",b=" + b);
int result = outer.methodSecond(a, b);
System.out.println("Leave methodSecond,result=" + result);
return result;
}
}
/**
* 测试代码
* @author hwz
*
*/
public class ProxyOuterClassTest {
public static void main(String[] args) {
InnerProxyClass proxy = new InnerProxyClass(new OneOuterClass());
proxy.methodOne("abcdef");
proxy.methodSecond(2, 3);
}
}
public interface InvocationHandler {
Object invoke(Object proxy, Method method, Object[] args);
}
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler handler)
/**
* 代理处理器
* @author hwz
*
*/
public class OutInterfaceInvokeHandler implements InvocationHandler {
private Object proxyObj;
public Object proxy(Object proxyObj) {
this.proxyObj = proxyObj;
return Proxy.newProxyInstance(proxyObj.getClass().getClassLoader(), proxyObj.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
StringBuilder builder = new StringBuilder();
if (args != null) {
for (int i=0; i<args.length; ++i) {
builder.append(",arg" + i + "=" + args[i].toString());
}
}
System.out.println("Enter " + method.toString() + ",args:" + builder.toString());
//此处proxy是生成代理类的实例
Object result = method.invoke(proxyObj, args);
System.out.println("Leave " + method + ",result=" + result.toString());
return result;
}
}
/**
* 测试代码
* @author hwz
*
*/
public class ProxyOuterClassTest {
public static void main(String[] args) {
OneOuterInterface outer = new OneOuterClass();
OutInterfaceInvokeHandler handler = new OutInterfaceInvokeHandler();
OneOuterInterface proxy = (OneOuterInterface) handler.proxy(outer);
proxy.methodOne("abcdef");
proxy.methodSecond(2, 4);
}
}
注意:InvocationHandler.invoke方法的第一个入参是动态生成代理类的实例对象引用,直接使用这个proxy调用方法会发生无限循环调用