栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java动态代理

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java动态代理

一、Java动态代理简介

Java动态代理机制中有两个重要的类和接口:InvocationHandler(接口)和 Proxy(类)是实现动态代理的核心。

        InvocationHandler接口:是  proxy代理类实例的调用处理程序  所实现的一个接口,每一个proxy代理实例都有一个关联的调用处理程序。在代理实例调用方法时,方法调用被编码分派到调用处理程序的invoke方法。每一个  动态代理类的调用处理程序  都必须实现InvocationHandler接口,并重写InvocationHandler接口的invoke()方法,并且每个代理类的实例都关联到了实现该接口的动态代理类调用处理程序中,当我们通过动态代理对象调用一个方法时候,这个方法的调用就会被转到实现InvocationHandler接口类的invoke方法来调用,invoke方法参数说明如下:

//重写InvocationHandler接口的invoke()方法

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {}

        Proxy类:是用来创建一个代理对象,其最常用的方法是newProxyInstance()方法。

//通过Proxy类的newProxyInstance()方法创建代理对象
//要代理哪个真实对象,就将该真实对象传进去,最后通过该真实对象来调用其方法
//通过Proxy类的newProxyInstance()方法创建代理对象
//要代理哪个真实对象,就将该真实对象传进去,最后通过该真实对象来调用其方法

public static Object newProxyInstance(ClassLoader loader, 
                                      Class[] interfaces, 
                                      InvocationHandler h) {}
二、具体举例

动态代理步骤:

1、创建需要代理的接口

2、创建需要代理的真实对象(类)

3、创建一个实现接口InvocationHandler的类(动态代理类(对象)的调用处理程序),它必须重写invoke方法

4、通过Proxy的静态方法newProxyInstance()创建一个代理类对象,通过代理调用方法

1、需要动态代理的接口:
//需要动态代理的接口
public interface People {
    //打招呼
    public String sayHello(String name);
    //说再见
    public String sayGoodBye();
}
2、需要代理的实际对象

定义一个Teacher类,实现People接口,这个类是需要代理的真实对象

//需要被代理的真实对象
public class Teacher implements People{

    @Override
    public String sayHello(String name) {
        System.out.println("你好!");
        return "Hello" + name;
    }

    @Override
    public String sayGoodBye() {
        System.out.println("再见!");
        return "GoodBye";
    }
}
3、动态代理类(对象)的调用处理程序

定义一个代理类的调用处理程序,每个 动态代理类的调用处理程序 都必须实现InvocationHandler接口,重写其中的invoke()方法;我们将要代理的真实对象传入代理对象的调用处理程序的构造函数中,最终代理对象的调用处理程序会调用真实对象的方法;当我们通过动态代理对象调用一个方法时候,这个方法的调用就会被转发到实现InvocationHandler接口类的invoke方法来调用

//动态代理类(对象)的调用处理程序

public class InvocationHandlerImpl implements InvocationHandler {

    //声明代理类中要代理的真实对象(为了普用性,声明为Object类型,可以传进来多种类型的要代理的真实对象)
    private Object realObject;

    //提供构造函数,给要代理的真实对象赋值(动态的把要代理的真实对象传进来)
    public InvocationHandlerImpl() {
    }
    public InvocationHandlerImpl(Object realObject) {
        this.realObject = realObject;
    }

    //重写InvocationHandler接口的invoke()方法
    
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //在真实对象执行之前,我们可以添加自己的操作
        System.out.println("真实代理对象执行前,我先干点啥!");

        Object invoke = method.invoke(realObject, args);

        //在真实对象执行之后,我们可以添加自己的操作
        System.out.println("真实代理对象执行后,我再干点啥!");

        return invoke;
    }
}
4、创建代理对象测试

通过Proxy的静态方法newProxyInstance()创建一个代理类对象,通过代理调用方法

public class dynamicProxyTest {

    public static void main(String[] args) {

        //创建我们需要代理的真实对象
        People realTeacher = new Teacher();

        //创建 代理对象的调用程序 的对象
        //将要代理的真实对象传入代理对象的调用处理的构造函数中,最终代理对象的调用处理程序会调用真实对象的方法
        InvocationHandler handler = new InvocationHandlerImpl(realTeacher);

        //通过Proxy类的newProxyInstance()方法创建代理对象
        //要代理哪个真实对象,就将该真实对象传进去,最后通过该真实对象来调用其方法
        
        People proxyInstance = (People) Proxy.newProxyInstance(realTeacher.getClass().getClassLoader(),
                                                                realTeacher.getClass().getInterfaces(),
                                                                handler);

//        System.out.println("动态代理生成的类:" + proxyInstance.getClass().getName());
//        System.out.println(proxyInstance.toString());

        String hello = proxyInstance.sayHello("爱神!");
        System.out.println("返回值:" + hello);

        System.out.println("@@@@@@@@@@@@@@@@@@@@@@@@@@@");

        String goodBye = proxyInstance.sayGoodBye();
        System.out.println("返回值:" + goodBye);

    }

}
执行结果如下图:

在Spring中的两大核心IOC和AOP中的AOP(面向切面编程)的思想就是动态代理,在代理类的前面和后面加上不同的切面组成面向切面编程。上面只使用了Proxy类中的newProxyInstance()静态方法(生成代理类的方法),但是它还有其它的几个方法:

getInvocationHandler:返回指定代理实例的调用处理程序
getProxyClass:给定类加载器和接口数组的代理类的java.lang.Class对象。
isProxyClass:当且仅当使用getProxyClass方法或newProxyInstance方法将指定的类动态生成为代理类时,才返回true。
newProxyInstance:返回指定接口的代理类的实例,该接口将方法调用分派给指定的调用处理程序。

Java 动态代理具体有如下四步骤:

通过实现 InvocationHandler 接口创建自己的调用处理器;
通过为 Proxy 类指定 ClassLoader 对象和一组 interface 来创建动态代理类;
通过反射机制获得动态代理类的构造函数,其唯一参数类型是调用处理器接口类型;
通过构造函数创建动态代理类实例,构造时调用处理器对象作为参数被传入。
————————————————

参考文章:

原文链接:https://blog.csdn.net/jiankunking/article/details/52143504
原文链接:https://blog.csdn.net/yaomingyang/article/details/80981004

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/943933.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号