在java中的代理(静态代理)中使用租房这个现实的例子说明了java中的静态代理。相比于静态代理,动态代理稍微复杂一点,在一般的应用程序编写过程中使用较少,主要在实现框架时使用的比较多。比较经典的就是在框架中用来实现AOP。学习动态代理技术对理解AOP有非常大的帮助。
与静态代理不同,动态代理类在代码编写时是不存在的,而是在运行时通过字节码技术动态产生的。下面是JDK的Proxy类提供的用来产生代理类对象的静态方法。
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h) throws IllegalArgumentException {
if (h == null) {
throw new NullPointerException();
}
/*
* Look up or generate the designated proxy class.
*/
Class cl = getProxyClass(loader, interfaces);
/*
* Invoke its constructor with the designated invocation handler.
*/
try {
Constructor cons = cl.getConstructor(constructorParams);
return (Object) cons.newInstance(new Object[] { h });
} catch (NoSuchMethodException e) {
throw new InternalError(e.toString());
} catch (IllegalAccessException e) {
throw new InternalError(e.toString());
} catch (InstantiationException e) {
throw new InternalError(e.toString());
} catch (InvocationTargetException e) {
throw new InternalError(e.toString());
}
}
该方法需要三个参数,第一个参数是用来加载动态代理的类加载器,第二个参数是代理实现的接口列表,第三个参数是一个InvocationHandler对象,动态代理会将所有的调用重定向到该对象上。分析一下这个方法的签名,首先,动态产生的代理类需要一个类加载器来加载,因此需要指定一个类加载器。其次,代理需要代理那些服务呢?因此需要一个需要代理实现的接口列表。最后,由于代理类是在运行时产生的,如何知道被代理的对象是什么?在代理的过程中代理逻辑在什么地方实现?这一切都是由第三个参数InvocationHandler的对象决定的。下面是使用动态代理实现的租房过程。
租接口:
public interface Renter {
public void rent();
public String getName();
}
租房人:
public class HouseRenter implements Renter {
private String name;
public HouseRenter(String name) {
this.name = name;
}
@Override
public void rent() {
System.out.println(name + "与房东商量价钱");
//假设价钱总是能商量好
System.out.println(name + "与房东签约");
}
@Override
public String getName() {
return name;
}
}
动态代理:
public class DynamicAgent {
public static Object createAgent(Class<?>[] interfaces, InvocationHandler handler) {
return Proxy.newProxyInstance(DynamicAgent.class.getClassLoader(), interfaces, handler);
}
}
InvocationHandler:
public class AgentInvocationHandler implements InvocationHandler {
private Renter renter;
public AgentInvocationHandler(Renter renter) {
this.renter = renter;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
String proxyName = proxy.getClass().getSimpleName();
System.out.println("我是代理: " + proxyName);
System.out.println(proxyName + "找到一个房源");//中介做的事情
System.out.println(proxyName + "联系到了房东");//中介做的事情
method.invoke(renter, args);
System.out.println(proxyName + "收到" + renter.getName() + "的中介费");//中介做的事情
return null;
}
Main:
public class RentHouse {
public static void main(String[] args) {
HouseRenter lilei = new HouseRenter("李蕾");
Renter agent = (Renter)DynamicAgent.createAgent(new Class<?>[]{Renter.class}, new AgentInvocationHandler(lilei));
agent.rent();
}
}
运行结果:
我是代理: $Proxy0
$Proxy0找到一个房源
$Proxy0联系到了房东
李蕾与房东商量价钱
李蕾与房东签约
$Proxy0收到李蕾的中介费
在这个例子中,我们没有实现具体的代理类,而是通过DynamicAgent.createAgent动态创建代理对象,代理的具体逻辑在AgentInvocationHandler中进行了实现。这看上去跟静态代理很像,但其实要比静态代理灵活的多,这体现在代理类可以在被创建的那一刻才知道要代理的接口是什么,在本例中就是main方法的第二行代码在调用createAgent时才告诉代理要代理的是Renter接口。
有一点需要主要,在Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)方法中,会判断第二个参数中的每个Class对象必须是接口,这也就是在使用有些框架的AOP技术时,需要被代理的对象必须implements接口的原因。
分享到:
相关推荐
JAVA静态代理和动态代理
java动态代理 完整版 java动态代理 完整版 java动态代理 完整版 java动态代理 完整版 java动态代理 完整版
1:静态代理出现的实际背景,静态代理时如何演化成动态代理 2: 动态代理demo 举例实际应用场景(载入数据库驱动的时候,使用AIDL与系统Servic进行通信) 3: 动态代理使用到基础理论:ClassLoader 加载.class字节码...
java动态代理实例 要想理解拦截器的知识 最好要先理解java动态代理这块
自己总结的代理模式和Java中的动态代理模式,有源码
Java 动态代理详解(学习资料);Java 动态代理详解(学习资料);Java 动态代理详解(学习资料);Java 动态代理详解(学习资料);Java 动态代理详解(学习资料);
使用JAVA中的动态代理实现数据库连接池
适用于初探java动态代理模式,精简易懂。
对代理模式与Java动态代理类的理解说明
java代理机制 JDK动态代理和cglib代理 详解
java 动态代理 简单实例 新手看看
更好的了解java动态代理的原理!
java反射和动态代理,详细说明反射和动态代理的方法和使用!
java jdk 动态代理 演示demo
java动态代理 public class HireProxy implements InvocationHandler { //被代理的真实角色 private Object obj; public HireProxy(Object obj) { super(); this.obj = obj; } //第二个参数method,被...
Java实现动态代理的两种方式。 相对来说cglib更加方便。可以实现为实现接口的类(非final类)
讲述JAVA的动态代理的原理,以及通过JAVA的动态代理来实现AOP。简洁,易懂,学习AOP的入门级文档
Java动态代理的helloworld,抛砖引玉吧
详细介绍了开发java动态代理用到的相关类,和动态代理类的特点!最后以完整示例代码的形式,展现了java动态代理开发的过程!
Word格式的Java中动态代理的介绍及实例,有详细注释。