Java高级基础-两种代理机制的实现

        对于Sbring框架中的一些部分,类似于AOP、RMI均存在使用代理机制执行方法的思想,代理机制实质上是通过反射机制得到另一个类的方法以及对象,不需要通过使用方法所在类的对象来调用此,且对于之前只能执行然后返回结果的方法进行处理,使得我们可以在方法执行前后进行相关操作,类似于取出或改变参数、得到结果以及修改结果。

        代理机制基于反射机制,由反射得到类的对象以及方法名称及参数。然后使用Proxy类,返回结果。代理机制的实现存在两种方案,第一种是JDKProxy,一种是CGLibProxy。二者的区别在与实现方式的不同,得到的代理对象不同,JDKProxy是使用接口来实现代理,换言之使用JDKProxy必须使用接口才可以实现,代理对象必须为一个接口的对象。而CGLibProxy则不需要接口,它的原理是使用继承,以给定对象的类作为基类,得到一个子类的实例化对象,从而调用父类的方法。但是使用CGLibProxy时必须保证他所代理的对象存在无参构造,因为在设置父类时使用的是无参构造的方法。

        最重要的一点是代理机制依然存在对于方法调用的权限!private修饰的方法均不能被代理机制调用。

具体实现过程如下:

JDKProxy的简单实现:

public static <T> T getProxy(T object) {
    Class<?> clazz = object.getClass();
    Class<?>[] interfaces = clazz.getInterfaces();
    ClassLoader classLoader = clazz.getClassLoader();
​
    return (T) Proxy.newProxyInstance(classLoader, interfaces, new InvocationHandler() {
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println("执行方法前......");
            Object result = method.invoke(object, args);
            System.out.println("执行方法后......");
            return result;
        }
    });
}

上面就是JDK代理机制的完整实现,传递进来一个接口类的实现类的对象,通过反射机制得到这个对象所属类的所有接口,最终得到一个接口类型的对象,使用此对象来调用方法,示例如下:

ClassOneImp one = new ClassOneImp();
ClassOne proxy = JDKProxy.getProxy(one);
int result = proxy.doOne(2, 4);
System.out.println("result: " + result);

结果如下:

可以看到我们在方法执行前后都可以进行处理,达到了我们使用代理机制的目的。

CGLibProxy的简单实现:

对于CGLibProxy我们需要提供一个cglib-nodep-2.1.3.jar包来得到一个Enhancer类的对象,以及他的一系列方法来实现代理机制。

如下:

public static <T> T getProxy(T object) {
    Enhancer enhancer = new Enhancer();
    enhancer.setSuperclass(object.getClass());
    enhancer.setCallback(new InvocationHandler() {
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println("执行方法前......");
            Object result = method.invoke(object, args);
            System.out.println("执行方法后......");
            return result;
        }
    });
    return (T) enhancer.create();
}

JDK代理机制使用了继承的思想,实现对象的代理。结果与JDK代理机制相差不大,测试如下:

ClassTwo two = new ClassTwo(2);
int result = CGLibProxy.getProxy(two).doTwo();
System.out.println(result);

        对于代理机制这里只是简单实现,在之后很多框架学习中都会再次使用到,它对于方法参数与结果的获取与修改也将会派上大用场。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值