java 代理模式二:动态代理
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java 代理模式二:动态代理相关的知识,希望对你有一定的参考价值。
java动态代理:
java动态代理类位于java.lang.reflect包下,一般主要涉及两个类: 1.Interface InvocationHandler
该接口中仅定义了一个方法:Object invoke(Object proxy,Method method,Object[] args)
第一个参数obj一般是代理类,method是被代理的方法,如上例中的request(), args是该方法中的参数数组,无参是为null
这个抽象方法在代理类中动态实现。
2.Proxy
protected Proxy(InvocationHandler h): 构造函数,用于给内部的invocation handler赋值。
static Class<?> getProxyClass(ClassLoader loader, Class<?>... interfaces) : loader是类装载器,interfaces是真实类所拥有的全部接口的数组。
static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) :
返回代理类的一个实例,返回后的代理类可以当作被代理类使用(可使用被代理类在Subject接口中声明过的方法)。
实例1:
定义一个接口
/* * 抽象角色类 * 定义一个接口 */ public interface Subject { public void request(); }
定义真实角色类,实现接口
/* * 真实角色类 */ public class RealSubject implements Subject{ @Override public void request() { System.out.println("From real subject"); } }
定义动态代理类,实现InvocationHandler接口,重写invoke方法
/* * 动态代理类,实现InvocationHandler接口,重写invoke方法 */ public class DynamicSubject implements InvocationHandler { //对真实类的对象的引用 private Object sub; public DynamicSubject(Object obj){ this.sub = obj; }
@Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("Before calling " + method); //通过反射来调用方法 method.invoke(sub, args); System.out.println("After calling " + method); return null; } }
测试
public class Client { public static void main(String[] args) { //真实类对象 RealSubject realSubject = new RealSubject(); //通过 动态类对象 获取类型 InvocationHandler handle = new DynamicSubject(realSubject); Class<?> classType = handle.getClass(); //生成代理 //动态生成一个类 实现了指定的接口 生成类的对象 转换成接口类型 handle是动态代理类的一个对象 Subject subject = (Subject)Proxy.newProxyInstance(classType.getClassLoader(), realSubject.getClass().getInterfaces(), handle); subject.request(); System.out.println(subject.getClass()); } }
通过这种方式,被代理的对象(RealSubject)可以在运行时动态改变,需要控制的接口(Subject接口)可以在运行时改变,控制的方式(DynamicSubject类)也可以动态改变,从而实现了非常灵活的动态代理关系。
以上是关于java 代理模式二:动态代理的主要内容,如果未能解决你的问题,请参考以下文章