本站消息

站长简介/公众号

  出租广告位,需要合作请联系站长


+关注
已关注

分类  

暂无分类

标签  

暂无标签

日期归档  

2024-11(1)

JDK动态代理

发布于2021-03-13 14:12     阅读(787)     评论(0)     点赞(26)     收藏(3)


JDK动态代理

1、概念

JDK动态代理是代理模式的一种实现方式,还有一种实现模式叫作cglib,区别主要是JDK是代理接口,而cglib是代理类。

其实如果我们学过spring-aop 就应该大概了解什么是动态代理,因为spring-aop的底层就是用动态代理实现的,没有学过没关系,我们不谈就是,我会用最简单的,清晰的语言告诉你们什么是动态代理;

例子:

比如,我们有一个蛋糕,我们想在蛋糕的里面存放一些水果,这时候,我们该怎样去做呢?
我们可以将蛋糕切开,在每一块的前后面存放不同的水果,能想象到吧

如果说这里例子还不能理解,那么再来一个:

假设 你和你女朋友是同桌,天天上课眉来眼去,老师很是不爽,于是想到一个办法,在你们中间插了一个爱学习的同学,这样子,既没有改变原来的座位,又成功满足了老师的要求,理解了吗?

我们的动态代理,也是如此
比如:在某一段代码你认为不是很好,或者说缺乏了逻辑性,你就可以使用动态代理为你的目标对象生成一个代理类,让这个代理类在这段代码的前后添加一些你自己觉得有逻辑性的代码,增强原代码

动态代理一般由Proxy 类和InvocationHandler 接口实现

Proxy:简而言之,就是为我们生成代理对象
.
InvocationHandler:每个代理实例都有一个关联的调用处理程序。 当在代理实例上调用方法时,方法调用将被编码并分派到其调用处理程序的invoke方法。 简而言之就是, 每一个动态代理类的调用处理程序都必须实现InvocationHandler接口,并且每个代理类的实例都关联到了实现该接口的动态代理类调用处理程序中,当我们通过动态代理对象调用一个方法时候,这个方法的调用就会被转发到InvocationHandler接口类的invoke方法来调用

具体操作,可以复制以下代码,执行一遍:

package com.javapandeng.mapper;

public interface Student {

    /**
     * 学习
     * @param name
     * @return
     */
    public void Study(String name) ;


    /**
     * 下课
     * @return
     */
    public String ClassIsOver();

}

实现类:

package com.javapandeng.mapper;

public class StudentImp  implements Student{

    @Override
    public void Study(String name) {
        System.out.println("Learning  "+name);

    }

    @Override
    public String ClassIsOver() {
        return "Good bye";
    }
}

代理类 (我定义,代理类的作用就是在学习的前后 输出两句话):

package com.javapandeng.mapper;

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

public class StudentProxy{

    public static Object getStudentProxy(){
        Student student = new StudentImp();
        /**
         * InvocationHandler接口是proxy代理实例的调用处理程序实现的一个接口
         */
        InvocationHandler invocationHandler = new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println("在此之前,我要午睡");  //方法之前输出
                Object result =  method.invoke(student,args);  //执行原方法
                System.out.println("下课了,回家吃饭了");  //方法之后输出
                return result;
            }
        };
        ClassLoader classLoader = student.getClass().getClassLoader(); //获取类加载器
        Class<?>[] interfaces =  student.getClass().getInterfaces();  //获取StudentImp实现的所有接口
        /**
         * Proxy类就是用来创建一个代理对象的类,它提供了很多方法,但是我们最常用的是newProxyInstance方法
         */
        Object object  =  Proxy.newProxyInstance(classLoader,interfaces,invocationHandler);
        return object ;
    }
}

测试类:

package com.javapandeng.mapper;

public class ProxyTest {

    public static void main(String[] args) {
       Student student = (Student) StudentProxy.getStudentProxy();
       student.Study("English");
    }
}

原文链接:https://blog.csdn.net/qq_46127735/article/details/114703903



所属网站分类: 技术文章 > 博客

作者:咿呀咿呀哟

链接:http://www.javaheidong.com/blog/article/114184/6d4f0e5b20edfd6f1710/

来源:java黑洞网

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

26 0
收藏该文
已收藏

评论内容:(最多支持255个字符)