JDK动态代理

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");
    }
}

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值