java动态代理
这个和反射不同的地方在于,这个东西有接口
这里话进行学习的话得需要四个java代码
一个接口和其他三个class
这里的IUser是一个接口
UserImpl是一个继承于IUser接口,里面重写了IUser接口里的show()方法
UserProxy也是一个继承IUser接口,里面也是重写了show方法
ProxyTest是个产生代理对象的类
在这个产生代理对象的类里边进行操作
这里因为UserImpl类是继承了IUser接口,所以这里的类型得定义为IUser.
然后这里就会调用UserImpl类里边的show方法
接下来使用另一个类
这里是会输出两个展示,因为UserProxy里面有一个有参构造函数,传的值是别人传入的对象,因为这里传入的对象是UserImpl的,所以在UserProxy调用show方法时,就会调用到UserImpl类里边的show方法
以上展示的就是静态代理了
动态代理
这里出现的动态代理就是因为静态代理有缺点,因为如果接口里面有很多函数的话,日志(UserImpl)里面也要重写很多函数的方法,代理类(UserProxy)里边也要重写很多类的方法。就会比较繁琐
这里要实现动态代理的话,就是得想要这个方法
这个方法限定了三个参数,前两个都是写死的,只要是最后一个,这个是关键(就是把想要做的东西传进去)
1 | Proxy.newProxyInstance(user.getClass().getClassLoader(), user.getClass().getInterfaces(),xxx); |
这个xxx就是我们要做的事情
所以我们得先新建一个类
然后对这个invoke进行重写
这里和前面的那个代理类差不多,但是这里用的InvocationHandler这个类,
这个invoke函数,只要我们能传进来东西,他就会知道我们调用的是哪个方法,这是这个函数的性质
我们就到代理测试类那边进行调试
1 | InvocationHandler invocationHandler = new UserinvocationHandler(user); |
我们就是利用这个invocationHandler这个类来进行动态代理,所以在new一个对象的时候,我们就用它。
然后再把实例化后的对象放进下面的Proxy.newProxyInstance里;
然后就可以直接调用这个方法了
在这个类里边新加这个方法的话,就可以直接调用了了,就不用再去代理类里边重写函数的方法了,这样的话就大大减少了代码量
1 | IUser user1 = (IUser) Proxy.newProxyInstance(iUser.getClass().getClassLoader(), iUser.getClass().getInterfaces(),invocationHandler); |
这里的代码也可以写成这样
1 | IUser user1 = (IUser) Proxy.newProxyInstance(iUser.getClass().getClassLoader(), new Class[]{IUser.class},invocationHandler); |
跟这个有关