Client---->Interface A
-- --
代理类 Class AImpl
代理类是动态生成的,借助Proxy类和InvocationHandler接口进行实现,InvocationHandler的invoke函数就是调用目标类实现的功能接口的地方,可以在这里进行访问控制,添加额外的处理逻辑。
使用方法:1,通过实现InvocationHandler接口创建自己的调用处理器。2,通过Proxy类的newProxyInstance函数创建动态代理类。
Example:
public interface Chatroom{
abstract public void createChatroom();
}
public class ChatroomImpl{
public void createChatroom() {
System.out.println("Chatroom is created!");
}
}
public class ChatInvocationHandler implements InvocationHandler{
private static int count=0;
private Object target;
public ChatInvocationHandler(Object target){
this.target=target;
}
public void setTarget(Object target){
this.target=target;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable{
if(count++%2==0){
return method.invoke(target, args); //Control in what circumtances invoke the method of ChatroomImpl.
}
System.out.println("Cannot create chatroom!");
return null;
}
}
主函数进行调用:
ChatInvocationHandler chatHandler = new ChatInvocationHandler(new ChatroomImpl());
Chatroom proxy = (Chatroom)Proxy.newProxyInstance(Chatroom.class.getClassLoader(), new Class[]{Chatroom.class}, chatHandler);
for(int i=0; i<10; i++){
if(proxy!=null)
proxy.createChatroom();
}
这个proxy object就如同implement了Chatroom interface,在call createChatroom()函数的时候,是走的chatHandler的invoke函数,然后再逻辑性地调用原本目标类ChatroomImpl的createChatroom()函数。
In my old project, there is the LFIXBuilderHandler which implements InvocationHandler,在创建proxy的时候Proxy.newProxyInstance(LFIXProxy.class.getClassLoader(), classList(type=LFIXBuilder), handler)。这里LFIXBuilder是generate出来的interface,含有无数的fix field method with tag annotation,如果你创建impl class来set 你的message会非常麻烦,所以通过proxy的invoke(Object proxy, Method method, Object[] args)方法,可以统一地定义如何set message fields。