在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. css3 -- 颜色与不透明度

    1.opacity: opacity的值会被它的所有子元素继承,也就是说不可能让一个元素比他的父元素更加不透明,但你可以让他变得更透明点 Firefox  Webkit  Opera支持,注意IE 2 ...

  2. 关于jquery中 跳出each循环的方法

    最近在项目中用带了jquery,在使用each循环遍历时在满足一定条件就跳出,发现break不好使,最终原来 用 return false;便可解决.

  3. MVC 异常处理机制

    方法一 :web.config配置文件的 system.web 接点下添加,若为On则不会将异常信息反馈到用户,而是友好的跳转到error.htm <customErrors mode=&quo ...

  4. 期望+DP ZOJ 3929 Deque and Balls

    题目链接 题意:给你n个数,按照顺序依次放入一个双端队列(可放在头部,也可以放在尾部),求xi > xi+1的期望 * 2^n mod (1e9 +7) 分析:期望*2^n=出现这种排法的概率* ...

  5. 贪心 Codeforces Round #287 (Div. 2) A. Amr and Music

    题目传送门 /* 贪心水题 */ #include <cstdio> #include <algorithm> #include <iostream> #inclu ...

  6. 把Actor绑定到角色的插槽上

    void AMonster::PostInitializeComponents(){ Super::PostInitializeComponents(); // instantiate the mel ...

  7. 错误修改/etc/fstab,导致系统无法开机

    enter password or type control-D to continue 系统提示你输入root密码,而输入以后系统的所有文件是只读的,你无法修改 看下你的/etc/fstab这个目录 ...

  8. HDU5863 cjj's string game(DP + 矩阵快速幂)

    题目 Source http://acm.split.hdu.edu.cn/showproblem.php?pid=5863 Description cjj has k kinds of charac ...

  9. Shell 编程基础之 Select 练习

    一.语法 select 变量 in con1 con2 con3 # 自动列出 con1,con2,con3 的选择菜单 do #执行内容 break # select本身就是一个循环,break是当 ...

  10. ACM Longest Repeated Sequence

    Description You are given a sequence of integers, A = a1, a2, ... an. A consecutive subsequence of A ...