静态代理
为了解决缺点 使用动态代理
jdk动态代理 使用接口
cglib 使用类
javasisit 字节码
接口
动态代理类 (以下简称为代理类 )是一个实现在类创建时在运行时指定的接口列表的类,具有如下所述的行为。 代理接口是由代理类实现的接口。 代理实例是代理类的一个实例。 每个代理实例都有一个关联的调用处理程序对象,它实现了接口InvocationHandler 。 通过其代理接口之一的代理实例上的方法调用将被分派到实例调用处理程序的invoke方法,传递代理实例,
java.lang.reflect.Method
被调用方法的java.lang.reflect.Method
对象以及包含参数的类型Object
Object的数组。 调用处理程序适当地处理编码方法调用,并且返回的结果将作为方法在代理实例上调用的结果返回。代理类具有以下属性:
- 代理类是公共的,最终的,而不是抽象的,如果所有代理接口都是公共的。
- 如果任何代理接口是非公开的,代理类是非公开的,最终的,而不是抽象的 。
- 代理类的不合格名称未指定。 然而,以字符串
"$Proxy"
开头的类名空间应该保留给代理类。- 一个代理类扩展了
java.lang.reflect.Proxy
。- 代理类完全按照相同的顺序实现其创建时指定的接口。
- 如果一个代理类实现一个非公共接口,那么它将被定义在与该接口相同的包中。 否则,代理类的包也是未指定的。 请注意,程序包密封不会阻止在运行时在特定程序包中成功定义代理类,并且类也不会由同一类加载器定义,并且与特定签名者具有相同的包。
- 由于代理类实现了在其创建时指定的所有接口,
getInterfaces
在其类
对象上调用getInterfaces
将返回一个包含相同列表接口的数组(按其创建时指定的顺序),在其类
对象上调用getMethods
将返回一个数组的方法
对象,其中包括这些接口中的所有方法,并调用getMethod
将在代理接口中找到可以预期的方法。- Proxy.isProxyClass方法将返回true,如果它通过代理类 - 由
Proxy.getProxyClass
返回的类或由Proxy.newProxyInstance
返回的对象的类 - 否则为false。- 所述
java.security.ProtectionDomain
代理类的是相同由引导类装载程序装载系统类,如java.lang.Object
,因为是由受信任的系统代码生成代理类的代码。 此保护域通常将被授予java.security.AllPermission
。- 每个代理类有一个公共构造一个参数,该接口的实现InvocationHandler ,设置调用处理程序的代理实例。 而不必使用反射API来访问公共构造函数,也可以通过调用Proxy.newProxyInstance方法来创建代理实例,该方法将调用Proxy.getProxyClass的 *** 作与调用处理程序一起调用构造函数。
package com.kuang.demo03;
public interface Rent {
public void rent();
}
实现类
package com.kuang.demo03;
public class Host implements Rent {
public void rent() {
System.out.println("房东要出租房子!");
}
}
代理类
package com.kuang.demo03;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
//等会我们会有这个类,自动生成代理类
public class ProxyInvocationHandler implements InvocationHandler {
/*
Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),
new Class>[] { Foo.class },
handler);
//被代理的接口
*/
private Rent rent;
public void setRent(Rent rent) {
this.rent = rent;
}
//生成得到代理类
public Object getProxy(){
return Proxy.newProxyInstance(this.getClass().getClassLoader(),rent.getClass().getInterfaces(),this);
}
//处理代理实例,并返回结果
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//动态代理的本质,就是使用反射机制实现!
seeHouse();
Object result = method.invoke(rent, args);
fare();
return result;
}
public void seeHouse(){
System.out.println("中介带着看房子");
}
public void fare(){
System.out.println("中介收费房价一半");
}
}
测试类
package com.kuang.demo03;
public class Client {
public static void main(String[] args) {
//真实角色
Host host = new Host();
//代理角色 : 现在没有
ProxyInvocationHandler pih = new ProxyInvocationHandler();
//通过调用程序处理角色来处理我们要调用的接口对象!
pih.setRent(host);
Rent proxy = (Rent)pih.getProxy();
proxy.rent();
}
}
结构图和最终效果
官方源码
public class Proxy extends Object implements Serializable
Proxy
提供了创建动态代理类和实例的静态方法,它也是由这些方法创建的所有动态代理类的超类。为某个接口创建代理
Foo
:InvocationHandler handler = new MyInvocationHandler(...); Class> proxyClass = Proxy.getProxyClass(Foo.class.getClassLoader(), Foo.class); Foo f = (Foo) proxyClass.getConstructor(InvocationHandler.class). newInstance(handler);或更简单地:
Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(), new Class>[] { Foo.class }, handler);
方法摘要
所有方法 静态方法 具体的方法 Modifier and Type Method and Description static InvocationHandler
getInvocationHandler(Object proxy)
返回指定代理实例的调用处理程序。
static 类>
getProxyClass(ClassLoader loader, 类>... interfaces)
给出类加载器和接口数组的代理类的
java.lang.Class
对象。static boolean
isProxyClass(类> cl)
如果且仅当使用
getProxyClass
方法或newProxyInstance
方法将指定的类动态生成为代理类时,则返回true。static Object
newProxyInstance(ClassLoader loader, 类>[] interfaces, InvocationHandler h)
返回指定接口的代理类的实例,该接口将方法调用分派给指定的调用处理程序。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)