代理:设计模式
代理模式是一种常用的设计模式,其目的就是为其他对象提供一个代理以控制对某个真实对象的访问。代理类负责为委托类预处理消息,过滤消息并转发消息,以及进行消息被委托类执行后的后续处理。
为了方便说明,这里写一个简单的例子来实现动态代理。
- //抽象角色(动态代理只能代理接口)
- public interface Subject {
- public void request();
- }
- //真实角色:实现了Subject的request()方法
- public class RealSubject implements Subject{
- public void request(){
- System.out.println("From real subject.");
- }
- }
- //实现了InvocationHandler
- public class DynamicSubject implements InvocationHandler
- {
- private Object obj;//这是动态代理的好处,被封装的对象是Object类型,接受任意类型的对象
- public DynamicSubject()
- {
- }
- public DynamicSubject(Object obj)
- {
- this.obj = obj;
- }
- //这个方法不是我们显示的去调用
- public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
- {
- System.out.println("before calling " + method);
- method.invoke(obj, args);
- System.out.println("after calling " + method);
- return null;
- }
- }
- //客户端:生成代理实例,并调用了request()方法
- public class Client {
- public static void main(String[] args) throws Throwable{
- // TODO Auto-generated method stub
- Subject rs=new RealSubject();//这里指定被代理类
- InvocationHandler ds=new DynamicSubject(rs);
- Class<?> cls=rs.getClass();
- //以下是一次性生成代理
- Subject subject=(Subject) Proxy.newProxyInstance(
- cls.getClassLoader(),cls.getInterfaces(), ds);
- }
- }
以下是进行分析的过程:
java动态代理的类和接口(jdk1.6源码)
1,java.lang.reflect.Proxy:动态代理机制的主类,提供一组静态方法为一组接口动态的生成对象和代理类。
主要的方法有四个:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
源码如下(写的简单,可以自行)
-
package java.lang.reflect;
import ...
public class Proxy implements java.io.Serializable {
private static final Class<?>[] constructorParams ={ InvocationHandler.class };
// 方法 1: 该方法用于获取指定代理对象所关联的调用处理器
@CallerSensitive
public static InvocationHandler getInvocationHandler(Object proxy)
throws IllegalArgumentException
{
if (!isProxyClass(proxy.getClass())) {
throw new IllegalArgumentException("not a proxy instance");
}
final Proxy p = (Proxy) proxy;
final InvocationHandler ih = p.h;
if (System.getSecurityManager() != null) {
Class<?> ihClass = ih.getClass();
Class<?> caller = Reflection.getCallerClass();
if (ReflectUtil.needsPackageAccessCheck(caller.getClassLoader(),
ihClass.getClassLoader()))
{
ReflectUtil.checkPackageAccess(ihClass);
}
}
return ih;
} -
// 方法 2:该方法用于获取关联于指定类装载器和一组接口的动态代理类的类对象
public static boolean isProxyClass(Class<?> cl) {
return Proxy.class.isAssignableFrom(cl) && proxyClassCache.containsValue(cl);
} -
// 方法 3:该方法用于判断指定类对象是否是一个动态代理类
@CallerSensitive
public static Class<?> getProxyClass(ClassLoader loader,
Class<?>... interfaces)
throws IllegalArgumentException
{
final Class<?>[] intfs = interfaces.clone();
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
}
return getProxyClass0(loader, intfs);
}
// 方法 4:该方法用于为指定类装载器、一组接口及调用处理器生成动态代理类实例
CallerSensitive
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
{
Objects.requireNonNull(h);
final Class<?>[] intfs = interfaces.clone();
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
}
Class<?> cl = getProxyClass0(loader, intfs);
try {
if (sm != null) {
checkNewProxyPermission(Reflection.getCallerClass(), cl);
}
final Constructor<?> cons = cl.getConstructor(constructorParams);
final InvocationHandler ih = h;
if (!Modifier.isPublic(cl.getModifiers())) {
AccessController.doPrivileged(new PrivilegedAction<Void>() {
public Void run() {
cons.setAccessible(true);
return null;
}
});
}
return cons.newInstance(new Object[]{h});
} catch (IllegalAccessException|InstantiationException e) {
throw new InternalError(e.toString(), e);
} catch (InvocationTargetException e) {
Throwable t = e.getCause();
if (t instanceof RuntimeException) {
throw (RuntimeException) t;
} else {
throw new InternalError(t.toString(), t);
}
} catch (NoSuchMethodException e) {
throw new InternalError(e.toString(), e);
}
}
}
2,java.lang.reflect.InvocationHandler:调用处理器接口,自定义invokle方法,用于实现对于真正委托类的代理访问。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
3,java.lang.ClassLoader:类装载器类,将类的字节码装载到 Java 虚拟机(JVM)中并为其定义类对象,然后该类才能被使用。Proxy类与普通类的唯一区别就是其字节码是由 JVM 在运行时动态生成的而非预存在于任何一个 .class 文件中。
每次生成动态代理类对象时都需要指定一个类装载器对象:newProxyInstance()方法第一个参数
java动态代理创建对象的过程为如下步骤:
1,通过实现 InvocationHandler 接口创建自己的调用处理器;
- 1
- 2
- 3
2,通过为 Proxy 类指定 ClassLoader 对象和一组 interface 来创建动态代理类;
- 1
- 2
3,通过反射机制获得动态代理类的构造函数,其唯一参数类型是调用处理器接口类型;
- 1
- 2
4,通过构造函数创建动态代理类实例,构造时调用处理器对象作为参数被传入。
- 1
- 2
为了简化对象创建过程,Proxy类中的newProxyInstance方法封装了2~4,只需两步即可完成代理对象的创建
- //真实角色:实现了Subject的request()方法
- public class RealSubject implements Subject{
- public void request(){
- System.out.println("From real subject.");
- }
- }