动态代理其实就是java.lang.reflect.Proxy类动态的根据您指定的所有接口生成一个class byte,该class会继承Proxy类,并实现所有你指定的接口(您在参数中传入的接口数组);然后再利用您指定的classloader将 class byte加载进系统,最后生成这样一个类的对象,并初始化该对象的一些值,如invocationHandler,以即所有的接口对应的Method成员。 初始化之后将对象返回给调用的客户端。这样客户端拿到的就是一个实现你所有的接口的Proxy对象。请看实例分析:
一 业务接口类
public interface BusinessProcessor { public void processBusiness(); }
二 业务实现类
public class BusinessProcessorImpl implements BusinessProcessor { public void processBusiness() { System.out.println("processing business....."); } }
三 业务代理类
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class BusinessProcessorHandler implements InvocationHandler { private Object target = null; BusinessProcessorHandler(Object target){ this.target = target; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("You can do something here before process your business"); Object result = method.invoke(target, args); System.out.println("You can do something here after process your business"); return result; } }
四 客户端应用类
import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.lang.reflect.Proxy; public class Test { public static void main(String[] args) { BusinessProcessorImpl bpimpl = new BusinessProcessorImpl(); BusinessProcessorHandler handler = new BusinessProcessorHandler(bpimpl); BusinessProcessor bp = (BusinessProcessor)Proxy.newProxyInstance(bpimpl.getClass().getClassLoader(), bpimpl.getClass().getInterfaces(), handler); bp.processBusiness(); } }
现在我们看一下打印结果:
processing business.....
You can do something here after process your business
通过结果我们就能够很简单的看出Proxy的作用了,它能够在你的核心业务方法前后做一些你所想做的辅助工作,如log日志,安全机制等等。
现在我们来分析一下上面的类的工作原理。
类一二没什么好说的。先看看类三吧。 实现了InvocationHandler接口的invoke方法。其实这个类就是最终Proxy调用的固定接口方法。Proxy不管客户端的业务方法是怎么实现的。当客户端调用Proxy时,它只
会调用InvocationHandler的invoke接口,所以我们的真正实现的方法就必须在invoke方法中去调用。关系如下:
BusinessProcessorImpl bpimpl = new BusinessProcessorImpl();
BusinessProcessorHandler handler = new BusinessProcessorHandler(bpimpl);
BusinessProcessor bp = (BusinessProcessor)Proxy.newProxyInstance(....);
bp.processBusiness()-->invocationHandler.invoke()-->bpimpl.processBusiness();
那么bp到底是怎么样一个对象呢。我们改一下main方法看一下就知道了:
public static void main(String[] args) {
BusinessProcessorImpl bpimpl = new BusinessProcessorImpl();
BusinessProcessorHandler handler = new BusinessProcessorHandler(bpimpl);
BusinessProcessor bp = (BusinessProcessor)Proxy.newProxyInstance(bpimpl.getClass().getClassLoader(), bpimpl.getClass().getInterfaces(), handler);
bp.processBusiness();
System.out.println(bp.getClass().getName());
}
输出结果:
You can do something here before process your business
processing business.....
You can do something here after process your business
$Proxy0
bp原来是个$Proxy0这个类的对象。那么这个类到底是长什么样子呢?好的。我们再写二个方法去把这个类打印出来看个究竟,是什么三头六臂呢?我们在main下面写如下两个静态方法。
public static String getModifier(int modifier){
String result = "";
switch(modifier){
case Modifier.PRIVATE:
result = "private";
case Modifier.PUBLIC:
result = "public";
case Modifier.PROTECTED:
result = "protected";
case Modifier.ABSTRACT :
result = "abstract";
case Modifier.FINAL :
result = "final";
case Modifier.NATIVE :
result = "native";
case Modifier.STATIC :
result = "static";
case Modifier.SYNCHRONIZED :
result = "synchronized";
case Modifier.STRICT :
result = "strict";
case Modifier.TRANSIENT :
result = "transient";
case Modifier.VOLATILE :
result = "volatile";
case Modifier.INTERFACE :
result = "interface";
}
return result;
}
public static void printClassDefinition(Class clz){
String clzModifier = getModifier(clz.getModifiers());
if(clzModifier!=null && !clzModifier.equals("")){
clzModifier = clzModifier + " ";
}
String superClz = clz.getSuperclass().getName();
if(superClz!=null && !superClz.equals("")){
superClz = "extends " + superClz;
}
Class[] interfaces = clz.getInterfaces();
String inters = "";
for(int i=0; i<interfaces.length; i++){
if(i==0){
inters += "implements ";
}
inters += interfaces[i].getName();
}
System.out.println(clzModifier +clz.getName()+" " + superClz +" " + inters );
System.out.println("{");
Field[] fields = clz.getDeclaredFields();
for(int i=0; i<fields.length; i++){
String modifier = getModifier(fields[i].getModifiers());
if(modifier!=null && !modifier.equals("")){
modifier = modifier + " ";
}
String fieldName = fields[i].getName();
String fieldType = fields[i].getType().getName();
System.out.println(" "+modifier + fieldType + " "+ fieldName + ";");
}
System.out.println();
Method[] methods = clz.getDeclaredMethods();
for(int i=0; i<methods.length; i++){
Method method = methods[i];
String modifier = getModifier(method.getModifiers());
if(modifier!=null && !modifier.equals("")){
modifier = modifier + " ";
}
String methodName = method.getName();
Class returnClz = method.getReturnType();
String retrunType = returnClz.getName();
Class[] clzs = method.getParameterTypes();
String paraList = "(";
for(int j=0; j<clzs.length; j++){
paraList += clzs[j].getName();
if(j != clzs.length -1 ){
paraList += ", ";
}
}
paraList += ")";
clzs = method.getExceptionTypes();
String exceptions = "";
for(int j=0; j<clzs.length; j++){
if(j==0){
exceptions += "throws ";
}
exceptions += clzs[j].getName();
if(j != clzs.length -1 ){
exceptions += ", ";
}
}
exceptions += ";";
String methodPrototype = modifier +retrunType+" "+methodName+paraList+exceptions;
System.out.println(" "+methodPrototype );
}
System.out.println("}");
}
再改写main方法
public static void main(String[] args) {
BusinessProcessorImpl bpimpl = new BusinessProcessorImpl();
BusinessProcessorHandler handler = new BusinessProcessorHandler(bpimpl);
BusinessProcessor bp = (BusinessProcessor)Proxy.newProxyInstance(bpimpl.getClass().getClassLoader(), bpimpl.getClass().getInterfaces(), handler);
bp.processBusiness();
System.out.println(bp.getClass().getName());
Class clz = bp.getClass();
printClassDefinition(clz);
}
现在我们再看看输出结果:
You can do something here before process your business
processing business.....
You can do something here after process your business
$Proxy0
$Proxy0 extends java.lang.reflect.Proxy implements com.tom.proxy.dynamic.BusinessProcessor
{
java.lang.reflect.Method m4;
java.lang.reflect.Method m2;
java.lang.reflect.Method m0;
java.lang.reflect.Method m3;
java.lang.reflect.Method m1;
void processBusiness();
int hashCode();
boolean equals(java.lang.Object);
java.lang.String toString();
}
很明显,Proxy.newProxyInstance方法会做如下几件事:
1,根据传入的第二个参数interfaces动态生成一个类,实现interfaces中的接口,该例中即BusinessProcessor接口的processBusiness方法。并且继承了Proxy类,重写了hashcode,toString,equals等三个方法。具体实现可参看 ProxyGenerator.generateProxyClass(...); 该例中生成了$Proxy0类
2,通过传入的第一个参数classloder将刚生成的类加载到jvm中。即将$Proxy0类load
3,利用第三个参数,调用$Proxy0的$Proxy0(InvocationHandler)构造函数 创建$Proxy0的对象,并且用interfaces参数遍历其所有接口的方法,并生成Method对象初始化对象的几个Method成员变量
4,将$Proxy0的实例返回给客户端。
现在好了。我们再看客户端怎么调就清楚了。
1,客户端拿到的是$Proxy0的实例对象,由于$Proxy0继承了BusinessProcessor,因此转化为BusinessProcessor没任何问题。
BusinessProcessor bp = (BusinessProcessor)Proxy.newProxyInstance(....);
2,bp.processBusiness();
实际上调用的是$Proxy0.processBusiness();那么$Proxy0.processBusiness()的实现就是通过InvocationHandler去调用invoke方法啦!
发表评论
-
JMX
2011-04-21 15:14 691Offical Usage Documents: http:/ ... -
[转]Java堆栈
2011-03-07 17:05 908Java把内存划分成两种: ... -
虚拟机查看命令verbose
2010-12-30 10:43 1123java -verbose[:class|gc|jni] ... -
JAVA中native方法
2010-12-30 09:57 745Java不是完美的,Java的不足除了体现在运行速度上要比传统 ... -
Java注释
2010-12-29 11:33 1049类、接口的注释采用 /** ... -
类加载体系结构原则
2010-12-28 15:39 787要理: 1. classLoader是一种父子树形结构(注:这 ... -
java数组
2010-12-25 16:18 1136java语言中,数组是一种 ... -
Ibatis的一些点
2010-12-15 20:37 7721.iBatis为一些类型定义了别名alias,以简化开发人员 ... -
我相信勤能补拙
2010-11-28 18:49 817我相信勤能补拙,七公的武功这么精湛,当然可以好好享受,可是我的 ... -
Java注解
2010-03-18 21:26 3714Java注解相当于对类或者方法或者变量额外的注释(标识)。以下 ... -
Java语言拾贝
2010-03-06 12:20 5211.volatile关键字 在Java中 ... -
SimpleDateFormat使用
2009-12-28 16:15 904public class SimpleDateFormat e ...
相关推荐
Java ProxyServer是一个基于Java实现的代理服务器类,它在客户端和服务器之间起到了中继的作用,允许数据在两者间传输。代理服务器在计算机网络中的主要功能是提供代理服务,它可以隐藏客户端的真实身份,增加网络...
Java实现HTTP PROXY是一个常见的需求,特别是在开发网络应用或者测试环境中,我们可能需要通过代理服务器转发HTTP请求。本文将深入探讨如何使用Java编程语言来创建一个HTTP代理服务器,并且会涉及相关的源码分析。 ...
在这个“java proxy demo”中,我们将深入探讨如何利用Sun JDK API来创建和使用Java动态代理。 首先,我们要了解Java代理的基本概念。Java代理分为静态代理和动态代理两种。静态代理是在编译时就已经确定代理类的...
在Java中,动态代理主要通过`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口来实现。Proxy类是用于创建一个代理对象,而InvocationHandler接口则定义了代理对象调用方法时的行为。 1. **...
Java中的动态代理主要通过`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口来实现。动态代理可以在运行时创建一个实现一组给定接口的新类,而无需知道实际的目标对象。代理类是在运行时动态...
我自己用eclipse写的java代码,可以直接用eclipse导入,也可以直接用java -jar proxy_sample.jar执行 代码量很小,尽量通过注释进行说明 本例实现了InvocationHandler接口,代码具有典型性 在研究代理模式(Proxy...
在标题“JavaProxy Demo”中提到的,这是一个展示Java动态代理功能的示例程序。动态代理通常用于实现AOP(面向切面编程)或者在不修改目标对象的情况下增加额外的功能,比如日志、事务管理、性能监控等。 在Java中...
**proxy.jsp** 是一个用Java编写的代理页面,适用于Java服务器环境,如Tomcat。它通过设置`esri.config.defaults.io.proxyUrl`来指定代理服务的URL,当ArcGIS JavaScript API请求需要跨域访问的资源时,会自动通过这...
JAVA 通过proxy代理方式访问internet资源,
JdkProxy.java
Java的Proxy机制是Java反射API的一部分,主要用于创建动态代理类和动态代理对象。它允许我们在运行时创建一个实现了特定接口的新类,这个新类的行为由我们提供的InvocationHandler对象控制。以下是对Java Proxy机制...
在Java中,我们可以使用`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口来实现。`Proxy`类用于创建代理对象,`InvocationHandler`接口定义了代理对象方法调用的处理逻辑。在"DynamicProxy...
Java Proxy 机制是Java语言提供的一种动态代理功能,允许我们在运行时创建一个新的类,这个类可以实现一组指定的接口,并且在方法调用时插入自定义的行为。这主要通过`java.lang.reflect.Proxy`类和`java.lang....
总的来说,"httpProxy-java"项目涉及的是使用Java实现HTTP代理服务的技术,涵盖了网络编程、HTTP协议、多线程以及可能的额外功能如性能优化和安全控制。通过对这些项目的研究和学习,开发者可以深入理解HTTP代理的...
标题中的“从房屋买卖看 java proxy 模式”暗示了我们将通过一个具体的场景来探讨 Java 中的代理(Proxy)模式。在软件设计中,代理模式是一种结构型设计模式,它为其他对象提供一种代理以控制对这个对象的访问。在...
Java Proxy机制详细解读 Java Proxy机制是Java语言中的一种设计模式,主要用于将对象的调用行为与实现解耦,提供了一个代理对象,使得外界无法直接访问目标对象,从而提高了系统的灵活性和可维护性。 Proxy机制的...
1. **Java Proxy Class**: Java的`java.lang.reflect.Proxy`类是动态代理的基石。它允许我们在运行时创建一个新的类,这个类可以作为其他接口的实现,这样我们就可以在调用接口方法时插入自定义的行为。在这个`java_...
NULL 博文链接:https://lgr310-163-com.iteye.com/blog/686040
Java版的代理(proxy)是Java编程中一个重要的概念,主要用在分布式系统或网络通信中,用于在客户端和服务器之间建立一个中间层,以实现负载均衡、安全控制、缓存、日志记录等多种功能。在Java中,代理通常通过Java...
本文将深入探讨Java中的动态代理,特别是基于`java.lang.reflect.Proxy`类的使用。 首先,`java.lang.reflect.Proxy`是Java标准库中用于生成动态代理类的关键类。它允许我们创建一个新的接口实现类,而无需手动编写...