动态代理

本文介绍了Java动态代理的概念及其两种实现方式:JDK提供的Proxy类和cglib库。详细解析了Proxy类的newProxyInstance方法参数,并通过示例展示了如何创建一个动态代理对象。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 动态代理是在代理模式基础上发展的,它不是对单一类型进行代理,而是可以对任意一个实现了接口的类的对象进行代理。动态代理可以实现拦截对真实对象的访问。

1. 动态代理的实现
 动态代理的实现由两种方式,一种是通过JDK提供的Proxy类来实现。这种方式要求被代理类必须实现接口。简单讲,就是只能为接口做代理。

 第二种是通过cglib来实现(这个是spring框架中的方法)。

2. 代理Proxy类
 Proxy提供用于创建动态代理类和实例的静态方法。在这个类中有个静态方法:static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h),它将返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用处理程序。下面来介绍这个方法的参数。
第一个参数loader:
loader是一个类加载器,在使用这个方法的时候,我们要传递的应该是这个被代理类的类加载器。我们如何获取类加载器呢?首先得到这个类的Class对象,在Class对象中提供了一种方法 getClassLoader()能够获取到这个类的类加载器。

第二个参数interfaces:
interfaces是一个Class[]数组,我们要传递的是这个被代理类中的所有的interface接口的Class对象。我们如何获取接口的Class数组对象呢?首先我们得到这个类的Class对象,然后在Class对象中提供了一种方法getInterfaces(),它返回的是Class[],就代表所实现接口的所有Class对象。

第三个参数h:
它的类型是InvocationHandler,这是一个接口。InvocationHandler 是代理实例的调用处理程序实现的接口。

3. InvocationHandler接口
 在InvocationHandler中只有个方法invok,现在我们来看看这个方法的详细分析。
public Object invoke(Object proxy, Method method, Object[] args),这个方法有三个参数,参数proxy就是代理对象。参数method就是调用方法,参数args就是调用方法的参数。而返回值就是真实行为执行后返回的结果,会传递给代理对象调用的方法。

4. 注意事项
 <1>Proxy类负责创建代理对象时,如果指定了handler(处理器),那么不管用户调用代理对象的什么方法,该方法都是调用处理器的invoke方法。

 <2>由于invoke方法被调用需要三个参数:代理对象、方法、方法的参数,因此不管代理对象哪个方法调用处理器的invoke方法,都必须把自己所在的对象、自己(调用invoke方法的方法)、方法的参数传递进来。
5. 动态代理实例
被代理实现的接口:

//定以一类男人,会拍照
public interface KindMan {
    public void photo();
}

被代理对象(陈冠希):

//陈冠希实现了这类人,具体化了拍照的方法
public class Cgx implements KindMan{

    public void photo() {
        System.out.println("陈冠希拍照。。。。");
    }
}

动态代理:

public class DproxyDemo {
    public static void main(String[] args) {
        //做一个陈冠希代理。
        final KindMan man = new Cgx();
        KindMan manProxy = (KindMan) Proxy.newProxyInstance(
            //第一个参数是类加载器
            man.getClass().getClassLoader(), 
            //第二个参数是实现接口的Class[]数组
            man.getClass().getInterfaces(),
                //第三个参数是一个处理器。这边以匿名的形式作为参数。
                new InvocationHandler() {
                    public Object invoke(Object proxy, Method method, Object[] args)
                            throws Throwable {
                        return method.invoke(man, args);
                    }
                });
        manProxy.photo();
    }
}

测试的结果为:
陈冠希拍照。。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值