JDK动态代理Demo

实现步骤:

1,创建接口,指定规范
2,目标类实现接口
3,创建获取代理类的类 (为什么这样说?因为代理类是运行时动态生成的,所以是在内存中,而且其类型是$Proxy0 ,如何进行分析可以用阿里巴巴的Arthas 来看,具体使用看最后的拓展),使用反射,对指定的方法进行扩展增强。往往借助使用的是Proxy.newProxyInstance,具体的参数传递代表含义看代码注释。

分布:

在这里插入图片描述

各个类描述:

SeckillTickets 接口:

package 代理对象.JDK动态代理;

//
public interface SeckillTickets {
    public void sell();
}

TrainStation 类工厂:

package 代理对象.JDK动态代理;

//目标类,类似于拥有货源的工厂。
public class TrainStation implements SeckillTickets {

    @Override
    public void sell() {
        System.out.println("这是TrainStation 的调用。");
    }
}

ProxyClass 类:

package 代理对象.JDK动态代理;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/*1,创建接口,指定规范
2,目标类实现接口
3,创建代理类,使用反射,对指定的方法进行扩展增强。往往借助使用的是Proxy.newProxyInstance,具体的参数传递代表含义看代码注释。*/
public class ProxyClass {
    public static void main(String[] args) {
        SeckillTickets target = new TrainStation();
        
        //第一个参数是获得目标类的类加载器。
        //第二个参数是目标类实现的所有接口。
        SeckillTickets proxy = (SeckillTickets) Proxy.newProxyInstance(target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        System.out.println("先执行扩展增强的方法");

                        //这里的method就代表,被代理的目标类的代理的方法,使用method.invoke()就是这样的写法,表示调用。
                        //method.invoke 的第一个参数是目标对象,第二个是传给方法的参数,这样就知晓了调用的是哪个目标对象的哪个方法。
                        Object invoke = method.invoke(target, args);
                        return invoke;
                    }
                });
        //这里来调用方法,这样就知晓了增强的是哪个方法。
        proxy.sell();
    }
}

拓展:

1,下载Arthas-boot的jar包
https://arthas.aliyun.com/arthas-boot.jar
2,上面的ProxyClass 类,在最后添加两行代码。

public class ProxyClass {

    public static void main(String[] args) {
        SeckillTickets target = new TrainStation();

        //第一个参数是获得目标类的类加载器。
        //第二个参数是目标类实现的所有接口。
        SeckillTickets proxy = (SeckillTickets) Proxy.newProxyInstance(target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        System.out.println("先执行扩展增强的方法");

                        //这里的method就代表,被代理的目标类的代理的方法,使用method.invoke()就是这样的写法,表示调用。
                        //method.invoke 的第一个参数是目标对象,第二个是传给方法的参数,这样就知晓了调用的是哪个目标对象的哪个方法。
                        Object invoke = method.invoke(target, args);
                        return invoke;
                    }
                });
        //这里来调用方法,这样就知晓了增强的是哪个方法。
        proxy.sell();

        //新添加的类。
        System.out.println(proxy.getClass().getName());
        while (true){

        }
    }
}

3,然后运行此类,得到:
在这里插入图片描述
4,运行Arthas。 按照
在这里插入图片描述
5,然后使用jad 命令 + 代理类的全名称,就可以得到代理类的全部信息。
在这里插入图片描述

其中有一个sell 方法:实际上上面使用代理对象调用的sell 方法是这个生成的代理类的sell 的方法。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值