JDK原装动态代理

JDK的动态代理类是指这样一种class,它是在运行时产生的class,在生成它时,你需要给它们提供一组接口,然后该class宣称它实现了这些接口。也因此你可以将该class的实例当做这些接口的任意实例来使用。当然这些动态代理类本质上还是Proxy,你需要为它指定InvocationHandler,由handler来接管实际的调用。在使用动态代理类时,我们为其实现handler。

import java.lang.reflect.InvocationHandler;  
import java.lang.reflect.Method;  
import java.lang.reflect.Proxy;  

可见主要是来自于jdk的反射包中。
一般涉及到的主要是两个类,也就是上面的InvocationHandler,以及Proxy。

InvocationHandler

这个接口中主要有一个方法

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable;
//这里的三个参数,proxy是代理对象target,method是target的方法,args表示target方法的参数列表

Proxy

该类是动态代理类,它的方法如下:

//这是一个构造函数,用于指定InvocationHandler
protected Proxy(InvocationHandler h);
//获取一个代理类,loader就是类加载器,而interfaces则是target类的所有接口的数组
static Class getProxyClass(ClassLoader loader,Class[] interfaces);

以及

//这是用于生成一个代理类实例对象的方法,其参数:loader就是类加载器,而interfaces则是真实类的所有接口的数组。这里返回的代理类可以当做委托类的实例使用。
static Object newProxyInstance(Classloader loader,Class[] interfaces,InvocationHandler h);

动态代理的实现步骤

  1. 自定义InvocationHandler实现,完成其invoke方法;
  2. 创建target类及其接口;
  3. 通过Proxy的newInstanceProxy()方法来创建代理类实例;
  4. 通过调用代理实例实现目标增强。
示例

目标类接口


public interface MyService {
    void doFirst();

    void doSecond();
}

接口实现

public class MyServiceImpl implements MyService {
    @Override
    public void doFirst() {
        System.out.println("this is first to do");
    }

    @Override
    public void doSecond() {
        System.out.println("this is first to do");
    }
}

代理使用匿名类实现InvocationHandler

public class ProxyWork {
    public static void main(String[] args){
        MyService target=new MyServiceImpl();
        MyService proxyService= (MyService) Proxy.newProxyInstance(MyService.class.getClassLoader(), target.getClass().getInterfaces(),
                new InvocationHandler() {
                    //proxy:代理对象
                    //method:对象方法
                    //args:对象方法参数列表
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        System.out.println("do advice operation before");
                        Object result=method.invoke(target,args);
                        System.out.println("do advice operation after");
                        return result;
                    }
                });
    }
}

在上面的实例中我犯了一个错误,因为目标类的方法是没有返回值得,所以在执行到

Object result=method.invoke(target,args);

时会抛出空指针异常。

参考文献:Java jdk动态代理原理分析

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值