Java动态代理机制的出现,使得Java程序员不需要手工编写代理类,只需要指定对应的接口及委托类对象,便能动态的获取代理类。代理类负责将所有方法的调用委托到实际对象反射执行,在委托中,代理类可以加入自定义功能的实现。
1,简介
普通静态代理模式,目的就是其他对象为了控制某对象的访问,而提供代理对象间接实现。
2,代理模式UML
3,角色介绍
ISubject:主题角色,定义对象的具体行为。
RealSubject:真实对象,被代理对象,实现主题角色,定义出具体行为。
Proxy:代理对象,一般实现主题角色,并持有真实对象的引用,在内部操作真实对象。
4,具体实现
静态代理的实现较为简单。具体可参考我之前的博客:http://blog.csdn.net/mergades/article/details/42173893
1,Java.lang.reflect.Proxy:该类主要提供静态方法用来创建代理对象。
* {@code Proxy} provides static methods for creating dynamic proxy
* classes and instances, and it is also the superclass of all
* dynamic proxy classes created by those methods.
getInvocationHandler方法:用于指定代理对象关联的调用处理器InvocationHandler。
public static InvocationHandler getInvocationHandler(Object proxy)
throws IllegalArgumentException
newProxyInstance:获取对应指定类加载器,以及接口的动态代理类对象。
@CallerSensitive
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
throws IllegalArgumentException
针对Proxy类,我们可以在它的Java doc文档中看到对应的描述:
-1,代理类最终都关联一个InvocationHandler接口,该接口用来处理针对代理类的所有方法调用。
-2,代理类必须是public,final而且不能为Abstract。因为是final的,所以不能再被继承。
-3,代理类必须是“$ProxyN” 的命名格式。因为代理类类部实现了缓存机制,所以并不是每次生成代理类对象都会是新的对象。针对同一组接口的连续调用,会从缓存获取代理对象。
-4,如果代理类实现了非公共接口,那么该接口必须与代理类出于相同的包中。接口数量不能超过65535。
2,java.lang.reflect.InvocationHandler:指定对应动态代理类的处理器。每次生成代理对象都必须指定该对象,可以参考proxy的newProxyInstance方法参数。
invoke方法:该方法负责集中处理针对动态代理类所有方法的调用。
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable;
主题接口:
package com.jing.proxy;
/**
* 主题接口
*
* @author jinglongjun
*
*/
public interface ISubject {
void doSomething();
}
真实对象:
package com.jing.proxy;
/**
* 具体的被代理对象。
*
* @author jinglongjun
*
*/
public class HelloSubject implements ISubject {
@Override
public void doSomething() {
System.out.println("HelloSubject: say hello to everyone!");
}
}
Handler对象:
package com.jing.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
* Handler对象
*
* @author jinglongjun
*
*/
public class SubHandler implements InvocationHandler {
private Object obj;// 持有真实对象
public SubHandler(Object obj) {
this.obj = obj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Object result = method.invoke(obj, args);// 真实对象来执行具体的方法
System.out.println("说完你好,说再见》》》bye-bye!");//加入自己操作
return result;
}
}
具体使用:
package com.jing.proxy;
import java.lang.reflect.Proxy;
public class Test {
public static void main(String[] args) {
HelloSubject helloSubject = new HelloSubject();
ISubject sub = (ISubject) Proxy.newProxyInstance(helloSubject.getClass()
.getClassLoader(), helloSubject.getClass().getInterfaces(),
new SubHandler(helloSubject));
sub.doSomething();
}
}
执行结果:
HelloSubject: say hello to everyone!
说完你好,说再见》》》bye-bye!
个人觉得,代码的重点还是在生成代理对象的时候,是如何将真实对象,和对应代理对象的InvocationHandler相互组装,实现我们最终需要的结果。具体就需要分析JDK的源码来看了。
具体源码,我们稍后分析。
本文主要参考:http://www.ibm.com/developerworks/cn/java/j-lo-proxy1/