JDK动态代理
Posted cwhan
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JDK动态代理相关的知识,希望对你有一定的参考价值。
记录下jdk动态代理
一个小白,记录学习遇到的坑
最近正在学习框架,初步了解了下什么是动态代理,记录下来,方便以后复习和修改。
首先代理是啥意思?
个人理解:
我们网购时,在淘宝、京东等平台上购买某件商品后,如果我们不满意,我们是不是可以退款?这就是起到一个代理的作用。
代理的作用
1、通俗的来讲,起到一个控制和增强的作用。
- 控制:上面的网购可以解释。
- 增强:可以理解为中间商赚差价。
代理的分类
分为静态代理和动态代理
下面说个例子来讲讲静态代理
静态代理
我们先定义一个U盘的接口
package com.han.usb;
public interface Usb {
float usbSell(int amount);
}
下面有个制作U盘的厂家,制作u盘。
package com.han.factory;
import com.han.usb.Usb;
public class UsbFactory implements Usb {
public float usbSell(int amount) {
float price=85.0f;
System.out.println("厂家出厂:"+price);
return price;
}
}
下面在创建个代理商。厂家通过这个代理商去联系更多的人,提高收入。
代理商也要吃饭是不是,所以啊这个代理商就赚了亿点点钱,并且还对
顾客说我们已经给了一张优惠卷。
package com.han.Tao;
import com.han.factory.UsbFactory;
import com.han.usb.Usb;
public class Taoproxy implements Usb {
@Override
public float usbSell(int amount) {
UsbFactory usbFactory=new UsbFactory();
float price=usbFactory.usbSell(amount);
price = (float) (price+25.0);
System.out.println("商家给你一个优惠卷,优惠了5快");
return price;
}
}
今天,小王看中了这个U盘,就找这个代理商买。
package com.han.customer;
import com.han.Tao.Taoproxy;
import com.han.usb.Usb;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class CustomerShop {
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
Taoproxy taoproxy=new Taoproxy();
// float price=taoproxy.usbSell(1);
Method method = Usb.class.getMethod("usbSell",int.class);
// int
// java.lang.Integer
// System.out.println(int.class.getName());
// System.out.println(Integer.class.getName());
float price= (float) method.invoke(taoproxy,1);
System.out.println("真好,真便宜,最后只花了"+price);
}
}
买完后,美滋滋!!!
这就是一个简单的静态例子,那么这么做的好处是什么了?
- 假如你的手里有个class文件,你完全不能改动其中的内容,但是这里面的功能不能实现你目前的业务,这时我们就可以通过代理来实现。
哈哈,这个例子我也不知道准不准确,我就继续编下去哈!
改动一个还好,我们只需要手动写几个代理类,但是如果改动100个了。哈哈,我回吐。
就没有什么办法吗? 有办法呀,什么办法了? 就是动态代理
动态代理
我目前只学了jdk动态代理,小声比比。
所谓的动态代理就是不能手动写代理商,交个jvm去动态生成。我们只需要写清楚我们所需要的功能。
那么怎么来实现动态代理了?
- 我们要实现一个接口InvocationHandler和创建一个代理(代理商)对象
我也没有完全搞明白是怎么创建出来的代理,今天先记录下来,以后在来补充。
先来实现这个接口
package com.han.Tao;
import com.han.usb.Usb;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class MyInvocationHandler implements InvocationHandler {
public Usb target;
public MyInvocationHandler(Usb target) {
this.target=target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//
float price= (float) method.invoke(target,args);
price=price+30.0f;
System.out.println("商家给你优惠卷");
return price;
}
}
解释:
实现这个接口就是要重写这个invoke方法,这个方法的参数解释
下面的参数解释仅仅在我目前的理解下做出的解释,错误重重!!!
- proxy:个人认为就是创建的代理对象
- method:显而易见就是我们需要调用的方法
- args:传入的参数,用在调用method方法时传入的参数
- target:就是你要代理的目标对象,也就是厂家
好,我们需要处理的业务逻辑代理已经完成了
下面再来创建代理类Proxy
创建代理类用到Proxy类中的一个静态方法,
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces, InvocationHandler h)
眨眼一看,我的妈呀,这都是啥?
我是晕,不知道您了?
来解释下参数:
- loader :类加载,加载一个类的字节码文件
- interfaces: 类实现的接口(可能有多个接口)信息
- h :我猜,这个就是proxy和invocationHandler连接起来的关键
这也就说明了JDK动态代理是需要有接口的
类加载没有了解过,勿喷啊!!!
package com.han.customer;
import com.han.Tao.MyInvocationHandler;
import com.han.factory.UsbFactory;
import com.han.usb.Usb;
import java.lang.reflect.Proxy;
public class MyProxy {
public static void main(String[] args) {
UsbFactory factory = new UsbFactory();
MyInvocationHandler myInvocationHandler = new MyInvocationHandler(factory);
Usb proxy = (Usb) Proxy.newProxyInstance(factory.getClass().getClassLoader(), factory.getClass().getInterfaces(), myInvocationHandler);
float price = proxy.usbSell(1);
System.out.println("真便宜,只用了"+price);
}
}
proxy.usbSell(1)执行到这儿时,会自动跳转到method.invoke(target,args),执行该方法。
我猜啊
这里的usbSell通过某种方式传给了method参数
而1则传给了args参数
今天先记录到这儿,勿喷啊,小白一个,我会努力的!!!
以上是关于JDK动态代理的主要内容,如果未能解决你的问题,请参考以下文章