详细参考资料https://www.ibm.com/developerworks/cn/java/j-lo-proxy1/
1.核心类:
java.lang.reflect.Proxy
:这是 Java 动态代理机制的主类,它提供了一组静态方法来为一组接口动态地生成代理类及其对象。
// 方法 1: 该方法用于获取指定代理对象所关联的调用处理器
static InvocationHandler getInvocationHandler(Object proxy)
// 方法 2:该方法用于获取关联于指定类装载器和一组接口的动态代理类的类对象
static Class getProxyClass(ClassLoader loader, Class[] interfaces)
// 方法 3:该方法用于判断指定类对象是否是一个动态代理类
static boolean isProxyClass(Class cl)
// 方法 4:该方法用于为指定类装载器、一组接口及调用处理器生成动态代理类实例
static Object newProxyInstance(ClassLoader loader, Class[] interfaces,
InvocationHandler h)
java.lang.reflect.InvocationHandler
:这是调用处理器接口,它自定义了一个 invoke 方法,用于集中处理在动态代理类对象上的方法调用,通常在该方法中实现对委托类的代理访问。
// 该方法负责集中处理动态代理类上的所有方法调用。第一个参数既是代理类实例,第二个参数是被调用的方法对象
// 第三个方法是调用参数。调用处理器根据这三个参数进行预处理或分派到委托类实例上发射执行
Object invoke(Object proxy, Method method, Object[] args)
2.简化的动态代理对象创建过程
// InvocationHandlerImpl 实现了 InvocationHandler 接口,并能实现方法调用从代理类到委托类的分派转发
InvocationHandler handler = new InvocationHandlerImpl(..);
// 通过 Proxy 直接创建动态代理类实例
Interface proxy = (Interface)Proxy.newProxyInstance( classLoader,
new Class[] { Interface.class },
handler );
3.参考实战示例-http://blog.csdn.net/lmj623565791/article/details/39275847
以下代码在上面实战示例的基础上进行解释的
DynamicHandler handler = new DynamicHandler(activity);
handler.addMethod(methodName, method);
Object listener = Proxy.newProxyInstance(listenerType.getClassLoader(),new Class<?>[] { listenerType }, handler);
import java.lang.ref.WeakReference;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.HashMap;
public class DynamicHandler implements InvocationHandler
{
private WeakReference<Object> handlerRef;
private final HashMap<String, Method> methodMap = new HashMap<String, Method>(
1);
public DynamicHandler(Object handler)
{
this.handlerRef = new WeakReference<Object>(handler);
}
public void addMethod(String name, Method method)
{
methodMap.put(name, method);
}
public Object getHandler()
{
return handlerRef.get();
}
public void setHandler(Object handler)
{
this.handlerRef = new WeakReference<Object>(handler);
}
//需要实现的核心方法
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable
{
Object handler = handlerRef.get();
if (handler != null)
{
//method就是代理的接口对象里面的方法对象,因为一个接口可以有很多方法,所以我们用一个map集合(methodMap)保存方法名,当某个方法被触发时,进行相应的操作
//这个methodName就是OnClickListener里的onClick
String methodName = method.getName();
//这个就是用注解替换onClick的方法,clickBtnInvoked
method = methodMap.get(methodName);
if (method != null)
{
//handler构造方法里面传了Activity进来,所以可以通过下面代码调用activity中的clickBtnInvoked。这样就通过代理的方式实现了方法的替换;
return method.invoke(handler, args);
}
}
return null;
}
}