jdk动态代理学习
在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动态代理学习的更多相关文章
- java jdk动态代理学习记录
转载自: https://www.jianshu.com/p/3616c70cb37b JDK自带的动态代理主要是指,实现了InvocationHandler接口的类,会继承一个invoke方法,通过 ...
- JDK动态代理学习心得
JDK动态代理是代理模式的一种实现方式,其只能代理接口.应用甚为广泛,比如我们的Spring的AOP底层就有涉及到JDK动态代理(此处后面可能会分享) 1.首先来说一下原生的JDK动态代理如何实现: ...
- AOP学习心得&jdk动态代理与cglib比较
什么是AOP AOP(Aspect-OrientedProgramming,面向方面编程),可以说是OOP(Object-Oriented Programing,面向对象编程)的补充和完善.OOP引入 ...
- aop学习总结一------使用jdk动态代理简单实现aop功能
aop学习总结一------使用jdk动态代理实现aop功能 动态代理:不需要为目标对象编写静态代理类,通过第三方或jdk框架动态生成代理对象的字节码 Jdk动态代理(proxy):目标对象必须实现接 ...
- 动态代理学习(二)JDK动态代理源码分析
上篇文章我们学习了如何自己实现一个动态代理,这篇文章我们从源码角度来分析下JDK的动态代理 先看一个Demo: public class MyInvocationHandler implements ...
- 动态代理学习(一)自己动手模拟JDK动态代理
最近一直在学习Spring的源码,Spring底层大量使用了动态代理.所以花一些时间对动态代理的知识做一下总结. 我们自己动手模拟一个动态代理 对JDK动态代理的源码进行分析 文章目录 场景: 思路: ...
- 学习CGLIB与JDK动态代理的区别
动态代理 代理模式是Java中常见的一种模式.代理又分为静态代理和动态代理.静态代理就是显式指定的代理,静态代理的优点是由程序员自行指定代理类并进行编译和运行,缺点是一个代理类只能对一个接口的实现类进 ...
- Java学习笔记--JDK动态代理
1.JDK动态代理 JDK1.3之后,Java提供了动态代理的技术,允许开发者在运行期创建接口的代理实例.JDK的动态代理主要涉及到java.lang.reflect包中的两个类:Proxy和 ...
- java学习笔记(中级篇)—JDK动态代理
一.什么是代理模式 相信大家都知道代理商这个概念,在商业中,代理商无处不在.假设你要去买东西,你不可能去找真正的厂家去买,也不可能直接跟厂家提出需求,代理商就是这中间的一桥梁,连接买家和厂商.你要买或 ...
随机推荐
- 浩瀚技术 安卓版移动开单手持微POS PDA无线移动开单软件 -安卓版移动手持开单设备
PDA数据采集器,是深圳浩瀚技术有限公司最新研发的一款安卓版移动手持开单设备,它通过WIFI和GPRS连接并访问电脑,从进销存软件中读取数据,实现移动开单,打破电脑开单模式. 它自带扫描器,可直接扫描 ...
- [转] FastMM使用详解
FastMM使用详解 一.引言 FastMM 是适用于delphi的第三方内存管理器,在国外已经是大名鼎鼎,在国内也有许多人在使用或者希望使用,就连 Borland 也在delphi2007 ...
- 5.19[bzoj树网的核]
围观了final,SJTU还是飞了,泽民同志劲啊! 膜拜归膜拜...回来开题 bzoj1999树网的核 最近就喜欢给自己找切不动的题...QAQ ok.....昨天在家里做了一个下午+晚上 又困&am ...
- 线段树(多维+双成段更新) UVA 11992 Fast Matrix Operations
题目传送门 题意:训练指南P207 分析:因为矩阵不超过20行,所以可以建20条线段的线段树,支持两个区间更新以及区间查询. #include <bits/stdc++.h> using ...
- 每天一个linux命令---netstat
中间件访问第三方服务,经常出现连不上的情况.可以增加监控,当出现异常的时候触发一些动作通知程序员 例如: 要在app 部署的主机上,应该登录 172.16.210.52 后运行 netstat - ...
- ural 1147. Shaping Regions
1147. Shaping Regions Time limit: 0.5 secondMemory limit: 64 MB N opaque rectangles (1 ≤ N ≤ 1000) o ...
- Rock-Paper-Scissors Tournament[HDU1148]
Rock-Paper-Scissors TournamentTime Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Ja ...
- JS 用sort方法排序字符串
JavaScript提供了一种更简便的方法用于比较两个字符串——localeCompare(),localeCompare()使用本地特定的顺序来比较两个字符串,语法如下:string.localeC ...
- topcoder SRM 623 DIV2 CatchTheBeatEasy
比较简单的一题,纠结比较久的是把my_cmp和my_minus放在类中,利用sort函数会出现 no matching function for call to ""sort(st ...
- js的小效果-图片放大镜效果
<!DOCTYPE html><html><head lang="en"> <meta charset="UTF-8" ...