Java代理

2019-11-20  本文已影响0人  losspm

前言

Java代理大致可以分为静态代理(static proxy),动态代理(dynamic proxy)。所谓代理,就是在原来对象的基础上代之行之。可以完全采用原对象的方法,又可以避免跟原对象产生必要的关联。我一般情况到只是认为,在原有对象上再隔离一层也许看起来有那么多余,但是对于单例模式的时候,并且需要构建相应的新对象时候,可以用上代理模式。比如房东 - 房产中介模式,之后看到更具体应用的介绍,在一般的项目中,所有的函数入口和出口增加日志记录,不可能去一条条的加入日志,因此需要引入代理模式

静态代理

假设有Permission相应接口

package proxyDemo;

public interface PermissionInterfaces {
    String getStatus();
    Boolean isGranted();
    void authorized();
}

有一个对象 permission giver

package proxyDemo;

public class PermissionProvider implements PermissionInterfaces {
    public String getStatus() {
        return 'NO_PERMISSION';
    }

    public Boolean isGranted() {
        return true;
    }

    public void authorized() { 

    }
}

其中,PermissionProvider有三个方法,分别为getStatus(); isGranted(); authorized()
此时,要用静态方法代理的话,即从PermissionProvider延伸出proxy类

package proxyDemo;

public class PermissionProviderProxy implements PermissionInterfaces {
    PermissionProvider permissionProvider;

    public PermissionProviderProxy (PermissionProvider permissionProvider) {
        this.permissionProvider = permissionProvider;
    }

    public String getStatus() {
        permissionProvider.getStatus();
    }
    public Boolean isGranted() {
        permissionProvider.isGranted();
    }
    public void authorized() {
        permissionProvider.authorized();
    }

}

在测试类中如下

package proxyDemo;

public class StaticProxyTest {
    public static void main(String[] args) {
        PermissionProvider permissionProvider = new PermissionProvider();

        PermissionInterfaces permissionProviderProxy = new PermissionProviderProxy(permissionProvider);

        permissionProviderProxy.getStatus();

    }
}

运行StaticProxyTest时候,会打印出Please tell me

静态代理目前存在的缺点就是,对于原本类,每一个方法都需要去实现,如果有1000个方法,则要在代理类手动去实现1000个方法,不具有很强的扩展性。静态代理偶尔写写demo以及小工具还行,遇到需要扩展的场景就有一定的局限性了

动态代理

为了避免每一次都去完全实现需要代理类的接口,此时我们需要利用到动态代理,主要涉及到的是JDK中的java.lang.reflect.InvocationHandler接口和 java.lang.reflect.Proxy类,主要入口是proxy。

proxy

Proxy类中提供了一个静态方法,getProxyClass(ClassLoader, interfaces),只需要传入ClassLoader(类加载器)以及interfaces就可以返回一个原Class的一个代理对象。并且返回出来的对象能够构造相应的实体出来,用之前看过的资料一句话来说,就是以Class构造Class。
但是实际编程中,一般使用Proxy.newProxyInstance(),直接返回代理实例,具体实例待补充;

JDK动态代理缺点

JDK的动态代理是基于接口进行代理,但是如果要代理一个类就只有普通方法时候,没有定义的interface,那么JDK的代理就不能使用了,此时得需要cglib对动态代理进行补充

上一篇下一篇

猜你喜欢

热点阅读