java 代理

代理是一种软件设计模式,目的地希望能做到代码重用。具体上讲,代理这种设计模式是通过不直接访问被代理对象的方式,而访问被代理对象的方法。
定义一个接口如下:

package com.org.base.proxy;

public interface BookOderService {

    public  void sell(int num);
}

定义一个实现类如下:

package com.org.base.proxy;

public class BookOderServiceImpl implements BookOderService {
    @Override
    public void sell(int num) {
        System.out.println("num = [" + num + "]");
    }
}

定义一个代理工具处理类ProxyHandler 实现InvocationHandler

package com.org.base.proxy;

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

public class ProxyHandler implements InvocationHandler {
    private Object object;
    public ProxyHandler(Object object) {
        this.object=object;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        /**
         * ①Object proxy:代理对象引用。
         * ②Method method:代理类中接受的接口方法。
         * ③Object[] args:向代理对象的方法中传递的参数。
         */
        System.out.println("<执行方法之前>");
        Object result = method.invoke(object, args);
        System.out.println("<执行方法之后>");
        return  result;
    }


}

测试主函数调用

package com.org.base.proxy;

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

public class Main {
    public static void main(String[] args) throws Exception {
        BookOderServiceImpl bookOderServiceImpl=new BookOderServiceImpl();
       BookOderService bookOderService=(BookOderService)Proxy.newProxyInstance(BookOderService.class.getClassLoader(),new Class[]{BookOderService.class},new ProxyHandler(bookOderServiceImpl));
        bookOderService.sell(1);
    }
}

Proxy源码分析:

public static Object newProxyInstance(ClassLoader loader,
                                          Class<?>[] interfaces,
                                          InvocationHandler h)
        throws IllegalArgumentException
    {
       //判断当前传入的代理类是否为空
        Objects.requireNonNull(h);
       // 对 interfaces 数组的浅拷贝
        final Class<?>[] intfs = interfaces.clone();
        
        final SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
        // 如果配置了安全管理器,那么需要确认 Proxy 有创建新的代理类的许可
            checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
        }

        /*
         * Look up or generate the designated proxy class.
         */
         // 调用  getProxyClass0
        Class<?> cl = getProxyClass0(loader, intfs);
        ......
}
调用getProxyClass0 方法:
private static Class<?> getProxyClass0(ClassLoader loader, Class<?>... interfaces) {
    // 确认需要进行增强的接口数量少于等于 65535,详细原因请去了解 ClassFile 规范(规范中的接口上限)
    if (interfaces.length > 65535) {
        throw new IllegalArgumentException("interface limit exceeded");
    }

    // 如果需要由指定 ClassLoader 加载, 实现给定 interfaces 的代理类已经存在, 
    // 将直接返回已经缓存过的拷贝
    // 否则,通过 ProxyClassFactory 创建新的代理类
    return proxyClassCache.get(loader, interfaces);
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值