在jdk的好多底层代码中很多都使用jdk的动态代理,下面就写写简单的代码来look look.

老规矩先上代码:

public interface SayDao {
public String sayChinese();
public String sayEnglish();
}
public class SayDaoImpl implements SayDao {
@Override
public String sayChinese() { return "我就是我!";
} @Override
public String sayEnglish() {
return "I am tom_plus!";
}
}
public class JDBCProxy implements InvocationHandler {
private Object target;
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("invoke begin!");
return method.invoke(target,args);
}
public Object bind(Object target) {
this.target = target;
return Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),this);
}
}
public class JDBCProxyTest {
public static void main(String[] args) {
JDBCProxy jdbcProxy = new JDBCProxy();
SayDao sayDao = (SayDao) jdbcProxy.bind(new SayDaoImpl());
String s = sayDao.sayChinese();
System.out.println(s);
System.out.println("----------------");
printClassDefinition(sayDao.getClass());
}
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("}");
} }

我的视角:

动态代理其实就是Proxy类动态的根据指定的所有接口生成一个class,该class会继承Proxy类,并实现所有指定的接口(在参数中传入的接口数组);然后再利用指定的classloader将 class加载进系统,最后生成这样一个类的对象,并初始化该对象的一些值,如invocationHandler,以即所有的接口对应的Method成员。 初始化之后将对象返回给调用的客户端。这样客户端拿到的就是一个实现所有的接口的Proxy对象。

从代码角度:

com.sun.proxy.$Proxy0 extends java.lang.reflect.Proxy implements com.springapp.test.SayDao
{
java.lang.reflect.Method m1;
java.lang.reflect.Method m0;
java.lang.reflect.Method m3;
java.lang.reflect.Method m4;
java.lang.reflect.Method m2;

boolean equals(java.lang.Object);
java.lang.String toString();
int hashCode();
java.lang.String sayChinese();
java.lang.String sayEnglish();
}

具体细节:

public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
参数一:类加载器,把创建的代理类class加载进系统。
参数二:被代理对象实现的接口 class数组
参数三:调度处理程序类,内有invoke()方法,代理的核心就是调InvocationHandler类的invoke(Object proxy, Method method, Object[] args)方法
,用于集中处理在动态代理类对象上的方法调用,通常在该方法中实现对委托类的代理访问。
注意点:Object proxy 这个参数,代表的是代理类对象。
调用这个方法,返回代理类 class。

jdk动态代理学习的更多相关文章

  1. java jdk动态代理学习记录

    转载自: https://www.jianshu.com/p/3616c70cb37b JDK自带的动态代理主要是指,实现了InvocationHandler接口的类,会继承一个invoke方法,通过 ...

  2. JDK动态代理学习心得

    JDK动态代理是代理模式的一种实现方式,其只能代理接口.应用甚为广泛,比如我们的Spring的AOP底层就有涉及到JDK动态代理(此处后面可能会分享) 1.首先来说一下原生的JDK动态代理如何实现: ...

  3. AOP学习心得&jdk动态代理与cglib比较

    什么是AOP AOP(Aspect-OrientedProgramming,面向方面编程),可以说是OOP(Object-Oriented Programing,面向对象编程)的补充和完善.OOP引入 ...

  4. aop学习总结一------使用jdk动态代理简单实现aop功能

    aop学习总结一------使用jdk动态代理实现aop功能 动态代理:不需要为目标对象编写静态代理类,通过第三方或jdk框架动态生成代理对象的字节码 Jdk动态代理(proxy):目标对象必须实现接 ...

  5. 动态代理学习(二)JDK动态代理源码分析

    上篇文章我们学习了如何自己实现一个动态代理,这篇文章我们从源码角度来分析下JDK的动态代理 先看一个Demo: public class MyInvocationHandler implements ...

  6. 动态代理学习(一)自己动手模拟JDK动态代理

    最近一直在学习Spring的源码,Spring底层大量使用了动态代理.所以花一些时间对动态代理的知识做一下总结. 我们自己动手模拟一个动态代理 对JDK动态代理的源码进行分析 文章目录 场景: 思路: ...

  7. 学习CGLIB与JDK动态代理的区别

    动态代理 代理模式是Java中常见的一种模式.代理又分为静态代理和动态代理.静态代理就是显式指定的代理,静态代理的优点是由程序员自行指定代理类并进行编译和运行,缺点是一个代理类只能对一个接口的实现类进 ...

  8. Java学习笔记--JDK动态代理

    1.JDK动态代理     JDK1.3之后,Java提供了动态代理的技术,允许开发者在运行期创建接口的代理实例.JDK的动态代理主要涉及到java.lang.reflect包中的两个类:Proxy和 ...

  9. java学习笔记(中级篇)—JDK动态代理

    一.什么是代理模式 相信大家都知道代理商这个概念,在商业中,代理商无处不在.假设你要去买东西,你不可能去找真正的厂家去买,也不可能直接跟厂家提出需求,代理商就是这中间的一桥梁,连接买家和厂商.你要买或 ...

随机推荐

  1. 仓库如何盘点 打印扫描一体PDA盘点机提升库存盘点效率

    仓库盘点是对仓储货品的收发结存等活动进行有效控制,保证仓储货品完好无损.帐物相符,确保生产正常进行,规范公司物料的盘点作业.盘点需人工操作,费时费力,PDA盘点机的出现大幅提升了盘点效率,减轻了工作人 ...

  2. 6754 Keyboard of a Mobile Telephone

    /*实践再次说明ch=getchar()的速度非常慢*/ /*大水题,不解释*/ #include<stdio.h> #include<string.h> int main() ...

  3. Monkeyrunner脚本中component快速定位方法

    在编写MonkeyRunner脚本过程中,会出现component这一项内容,很多人可能不知道怎么确认,其实这个主要是为了指定要测试的程序包名和主Activity名,我们可以用以下方法去进行确认: 1 ...

  4. HttpClient 使用

    Api支持 HttpClient 是基于Task的异步方法组,支持取消.超时异步特性,其可以分类为以下: Restful: GetAsync,PostAsync,DeleteAsync,PutAsyn ...

  5. Java类加载

    类的生命周期是: 在一个类编译完成之后,下一步就需要开始使用类,如果要使用一个类,肯定离不开JVM.在程序执行中JVM通过装载,链接,初始化这3个步骤完成. 类的装载是通过类加载器完成的,加载器将.c ...

  6. Leap Motion发布新平台,直击下一代移动端VR/AR手部追踪

    2013年,动作捕捉技术公司Leap Motion发布了面向PC的体感控制器,不过销量并不乐观.随着2014年虚拟现实技术的再一次兴起,它发布一款用于Oculus Rift的附加设备,从而正式登上VR ...

  7. 深入理解Java:注解(Annotation)基本概念

    转自:http://www.cnblogs.com/peida/archive/2013/04/23/3036035.html 竹子-博客(.NET/Java/Linux/架构/管理/敏捷) 什么是注 ...

  8. Android Immersive Mode (沉浸模式) 还是 Translucent Bars (透明状态栏)

    Immersive Mode (沉浸模式) 还是 Translucent Bars (透明状态栏) [科普]什么叫真正的“沉浸式”状态栏? 为什么在国内会有很多用户把「透明栏」(Translucent ...

  9. objective-c 多线程注意的问题

    1.资源竞争:当每个线程都去访问同一段内存时,会导致所谓i资源竞争问题,这时候可以通过“@synchronized block”将实例变量包围起来,创建一个互斥锁, 这样你就可以确保在互斥锁中的代码一 ...

  10. 【Eclipse】修改 编码格式

    eclipse 默认编码居然是GBK,js文件默认编码是ISO-....怎么可以这样呢? 都修改成UTF8的方法: 1.windows->Preferences...打开"首选项&qu ...