JDK动态代理

动态代理之——JDK动态代理

概述

        Spring AOP使用两种代理机制,JDK的动态代理便是其中之一,它主要涉及java.lang.reflect包中的两个类:ProxyInvocationHandler。其中InvocationHandler是一个接口,可以通过实现该接口定义横切逻辑,并通过反射机制调用目标的代码,动态的将横切逻辑和业务逻辑编织在一起。

优点

        对方法进行增强,可以在方法前后进行补充。

源码解析

1.通过调用Proxy类的newProxyInstance()方法创建代理对象:

public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)

参数:
ClassLoader:类加载器。用于加载代理对象的字节码的。和被代理对象使用相同的类加载器。固定写法。
Class[]:字节码数组。用于给代理对象提供方法。和被代理对象具有相同的方法。和被代理对象实现相同的接口,就会具有相同的方法。固定写法
InvocationHanlder:要增强的方法。此处是一个接口,我们需要提供它的实现类。通常写的是匿名内部类(也可编写实现类,这里两种方法都尝试的写一下)。
2. InvocationHandler接口定义invoke方法

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

参数:
proxy:是最终生成的代理实例,一般不会用到。
method:是被代理目标示例的某个具体方法,通过他可以发起目标实例方法的反射调用。
args:是被代理实例某个方法的参数,在方法反射调用时使用。

案例

结构:

在这里插入图片描述
Sale接口:

public interface Sale {
    public void sale(Float money);
}

Sale接口的实现类:

public class SaleImpl implements Sale {
    @Override
    public void sale(Float money) {
        System.out.println("以"+money+"的价格销售了一件产品");
    }
}

InvocationHandler的实现类:

public class InvocationHandlerImpl implements InvocationHandler {
    private Sale sale;
	//目标类对象
    public InvocationHandlerImpl(Sale sale) {
        this.sale = sale;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    //将目标对象传给method.invoke方法,并调用实例的方法
		Object invoke = method.invoke(sale, args);
        if ((Float) args[0] > 1500) {
            System.out.println("赚了");
        } else {
            System.out.println("亏了");
        }
        //没用被调用,不必理会
        return invoke;
    }
}

测试类:

public class SaleTest {
    @Test
    //1.通过编写InvocationHandler的实现类
    public  void testJDK01() {
        //创建目标对象
        SaleImpl sale01 = new SaleImpl();
        //调用Proxy的newProxyInstance方法创建代理对象对象
        InvocationHandler invocationHandlerImpl = new InvocationHandlerImpl(sale01);
        Sale proxySale = (Sale)Proxy.newProxyInstance(sale01.getClass().getClassLoader(), sale01.getClass().getInterfaces(), invocationHandlerImpl);
        proxySale.sale(2000f);
    }
    @Test
    //2.通过编写InvocationHandler匿名内部类
    public  void testJDK02(){
        //创建目标对象
        SaleImpl sale01 = new SaleImpl();
        //调用Proxy的newProxyInstance方法创建代理对象对象
        Sale proxySale = (Sale)Proxy.newProxyInstance(sale01.getClass().getClassLoader(), sale01.getClass().getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            //将目标对象传给method.invoke方法,并调用实例的方法
                Object invoke = method.invoke(sale01, args);
                if ((Float) args[0] > 1500) {
                    System.out.println("赚了");
                } else {
                    System.out.println("亏了");
                }
                //没用被调用,不必理会
                return invoke;
            }
        });
        proxySale.sale(2000f);
    }
 
}

输出:

2000.0的价格销售了一件产品
赚了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值