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調用方法會發生無限循環調用