JavaSE--重新学习_查漏补缺(15)--动态代理简单实现步骤

一、动态代理

  • 动态代理:客户通过代理类来调用其他对象的方法。可以在程序运行时根据需要动态创建被代理类的代理对象。
    另外介绍–静态代理:代理类和被代理类都是在编译期间确定下来,不利于程序的扩展。同时,每一个代理类只能为一个接口服务,这样程序开发中必然产生过多的代理。最好可以通过一个代理类完成全部的代理功能。

1.1动态代理的步骤即代码

  1. 创建一个实现接口InvocationHandler的类,它必须实现invoke方法,以完成代理的具体操作。

  2. 创建被代理的类以及接口

  3. 通过Proxy的静态方法newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h) 创建一个Subject接口代理

  4. 通过Subject代理调用RealSubject实现类(即被代理对象调用自己的方法)的方法

  • 以上步骤的代码实现

      1. 创建一个实现接口InvocationHandler的类
    
package ProxyDemo;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
 * 动态代理类
 * @author lby
 *
 */
public class ProxyDemo implements InvocationHandler {

    Object obj;//被代理的对象
    public ProxyDemo(Object obj){
        this.obj = obj;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println(method.getName()+"方法开始执行");

        Object result = method.invoke(this.obj,args);//执行的是指定代理对象的指定的方法

        System.out.println(method.getName()+ "方法执行结束");
        return result;
    }
}

	2. 创建被代理的类以及接口
package ProxyDemo;

public interface ITestDemo {
    void test1();
    void test2();
}

package ProxyDemo;

public class ITestDemoImpl implements ITestDemo {

    @Override
    public void test1() {
        System.out.println("执行了 test1 方法");
    }

    @Override
    public void test2() {
        System.out.println("执行了 test2 方法");
    }
}

3. 通过Proxy的静态方法**newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)** 创建一个Subject接口代理
4. 通过Subject代理调用RealSubject实现类(即被代理对象调用自己的方法)的方法
package ProxyDemo;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;

public class Test {
    public static void main(String[] args) {
        ITestDemo iTestDemo = new ITestDemoImpl();
        /**
		 * 注意:如果一个对象想要通过Proxy.newProxyInstance方法被代理,
		 * 那么这个对象的类一定要有相应的接口
		 * 就像本类中的ITestDemo接口和实现类TestDemoImpl
		 */
        iTestDemo.test1();
        iTestDemo.test2();
        System.out.println("======================");
/**
		 * 需求:
		 * 在执行test1和test2方法时需要加入一些东西
		 * 在执行方法前打印test1或test2开始执行
		 * 在执行方法后打印test1或test2执行完毕
		 * 打印的方法名要和当时调用方法保存一致
		 */
        InvocationHandler invocationHandler = new ProxyDemo(iTestDemo);
/**
		 * Proxy.newProxyInstance(ClassLoader, interfaces, h)
		 * 参数1是代理对象的类加载器
		 * 参数2是被代理的对象的接口
		 * 参数3是代理对象
		 * 
		 * 返回的值就成功被代理后对象,返回的是Object类型,需要根据当时的情况去转换类型
		 */
        ITestDemo iTestDemo1 = (ITestDemo) Proxy.newProxyInstance(invocationHandler.getClass().getClassLoader(),
                iTestDemo.getClass().getInterfaces(),invocationHandler);
        iTestDemo1.test1();
        iTestDemo1.test2();
    }
}

输出

执行了 test1 方法
执行了 test2 方法
======================
test1方法开始执行
执行了 test1 方法
test1方法执行结束
test2方法开始执行
执行了 test2 方法
test2方法执行结束
发布了34 篇原创文章 · 获赞 1 · 访问量 517

猜你喜欢

转载自blog.csdn.net/weixin_44185736/article/details/105054454