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动态代理
一.什么是代理模式 相信大家都知道代理商这个概念,在商业中,代理商无处不在.假设你要去买东西,你不可能去找真正的厂家去买,也不可能直接跟厂家提出需求,代理商就是这中间的一桥梁,连接买家和厂商.你要买或 ...
随机推荐
- 我的DbHelper数据操作类
其实,微软的企业库中有一个非常不错的数据操作类了.但是,不少公司(起码我遇到的几个...),对一些"封装"了些什么的东西不太敢用,虽然我推荐过微软的企业库框架了...但是还是要&q ...
- 【转】Python yield 使用浅析
转载地址: www.ibm.com/developerworks/cn/opensource/os-cn-python-yield/ Python yield 使用浅析 初学 Python 的开发者经 ...
- 如何让Ue4画面产生振动效果
可以使用CameraShake蓝图类,对应的C++类为UCameraShake. 这个类是通过修改PlayerController来达到效果
- Hadoop YARN资源隔离技术
YARN对内存资源和CPU资源采用了不同的资源隔离方案.对于内存资源,它是一种限制性资源,它的量的大小直接决定应用程序的死活,因为应用程序到达内存限制,会发生OOM,就会被杀死.CPU资源一般用Cgr ...
- iOS之04-方法的声明和实现
本次重点学习和理解OC对象方法的声明和定义 代码: /* 计算器类 方法: 1> 返回 π 2> 计算某个整数的平方 3> 计算两个整数的和 */ #import <Found ...
- codeforces round #234B(DIV2) C Inna and Huge Candy Matrix
#include <iostream> #include <vector> #include <algorithm> #include <utility> ...
- BZOJ 3732 题解
3732: Network Description 给你N个点的无向图 (1 <= N <= 15,000),记为:1…N. 图中有M条边 (1 <= M <= 30,000) ...
- BZOJ4500: 矩阵
Description 有一个n*m的矩阵,初始每个格子的权值都为0,可以对矩阵执行两种操作: 1. 选择一行, 该行每个格子的权值加1或减1. 2. 选择一列, 该列每个格子的权值加1或减1. 现在 ...
- Spring_手动获取Bean
1.SpringContextHolder.java package com.lkb.util; import org.springframework.context.ApplicationConte ...
- Node.js 手册查询-1-核心模块方法
Node.js 学习手册 标签(空格分隔): node.js 模块 核心模块 核心模块是被编译成二进制代码,引用的时候只需require表示符即可 os 系统基本信息 os模块可提供操作系统的一些基本 ...