Java代理
前言
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
对动态代理进行补充