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 代理模式二:动态代理的主要内容,如果未能解决你的问题,请参考以下文章

Java动态代理

Java动态代理

JDK 动态代理(原理 + 代码实现)

Java设计模式-代理模式之动态代理(附源代码分析)

Java 静态代理和动态代理

Android代理模式(静态代理,动态代理,Retrofit代理模式分析)